From cd50695fa46be40e57f8c745c3ebbb7bf7160fd4 Mon Sep 17 00:00:00 2001 From: Gareth Ma Date: Thu, 13 Jul 2023 19:48:11 +0300 Subject: [PATCH 001/216] Fix incorrect multiplication for GradedModularFormElement --- src/sage/modular/modform/element.py | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/src/sage/modular/modform/element.py b/src/sage/modular/modform/element.py index 4d2123abab1..da75cc62b74 100644 --- a/src/sage/modular/modform/element.py +++ b/src/sage/modular/modform/element.py @@ -3544,18 +3544,30 @@ def _mul_(self, other): TESTS:: sage: M = ModularFormsRing(1) - sage: f4 = ModularForms(1, 4).0; f6 = ModularForms(1, 6).0; - sage: F4 = M(f4); F6 = M(f6); + sage: F4 = M.0; F6 = M.1; sage: F4*F6 # indirect doctest 1 - 264*q - 135432*q^2 - 5196576*q^3 - 69341448*q^4 - 515625264*q^5 + O(q^6) + + This shows that the issue at :trac:`35932` is fixed:: + + sage: (F4 + M(1))^2 + 4 + 960*q + 66240*q^2 + 1063680*q^3 + 7961280*q^4 + 37560960*q^5 + O(q^6) """ GM = self.__class__ + parent = self.parent() f_self = self._forms_dictionary f_other = other._forms_dictionary f_mul = {} for k_self in f_self.keys(): for k_other in f_other.keys(): - f_mul[k_self + k_other] = f_self[k_self]*f_other[k_other] + if k_self + k_other not in f_mul: + k_weight = k_self + k_other + if k_weight == 0: + M = parent.base_ring() + else: + M = parent.modular_forms_of_weight(k_weight).change_ring(parent.base_ring()) + f_mul[k_self + k_other] = M(0) + f_mul[k_self + k_other] += f_self[k_self]*f_other[k_other] return GM(self.parent(), f_mul) def _lmul_(self, c): From 2f273c4ccaab7680dfb24f6150d3d3850ff88a31 Mon Sep 17 00:00:00 2001 From: grhkm21 <83517584+grhkm21@users.noreply.github.com> Date: Sat, 22 Jul 2023 03:45:08 +0300 Subject: [PATCH 002/216] Apply suggestions from code review Applying David's styling suggestions Co-authored-by: David Ayotte <34245930+DavidAyotte@users.noreply.github.com> --- src/sage/modular/modform/element.py | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/src/sage/modular/modform/element.py b/src/sage/modular/modform/element.py index da75cc62b74..f6416f268a7 100644 --- a/src/sage/modular/modform/element.py +++ b/src/sage/modular/modform/element.py @@ -3548,26 +3548,21 @@ def _mul_(self, other): sage: F4*F6 # indirect doctest 1 - 264*q - 135432*q^2 - 5196576*q^3 - 69341448*q^4 - 515625264*q^5 + O(q^6) - This shows that the issue at :trac:`35932` is fixed:: + This shows that the issue at :issue:`35932` is fixed:: sage: (F4 + M(1))^2 4 + 960*q + 66240*q^2 + 1063680*q^3 + 7961280*q^4 + 37560960*q^5 + O(q^6) """ GM = self.__class__ - parent = self.parent() f_self = self._forms_dictionary f_other = other._forms_dictionary f_mul = {} for k_self in f_self.keys(): for k_other in f_other.keys(): - if k_self + k_other not in f_mul: - k_weight = k_self + k_other - if k_weight == 0: - M = parent.base_ring() - else: - M = parent.modular_forms_of_weight(k_weight).change_ring(parent.base_ring()) - f_mul[k_self + k_other] = M(0) - f_mul[k_self + k_other] += f_self[k_self]*f_other[k_other] + try: + f_mul[k_self + k_other] += f_self[k_self]*f_other[k_other] + except KeyError: + f_mul[k_self + k_other] = f_self[k_self]*f_other[k_other] return GM(self.parent(), f_mul) def _lmul_(self, c): From 280ed2bce4ec6408468e0297384d9213132ee92e Mon Sep 17 00:00:00 2001 From: Gareth Ma Date: Sat, 22 Jul 2023 22:01:18 +0300 Subject: [PATCH 003/216] Fix pycodestyle-minimal linting --- src/sage/modular/modform/element.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/modular/modform/element.py b/src/sage/modular/modform/element.py index f6416f268a7..6e276935c34 100644 --- a/src/sage/modular/modform/element.py +++ b/src/sage/modular/modform/element.py @@ -3560,9 +3560,9 @@ def _mul_(self, other): for k_self in f_self.keys(): for k_other in f_other.keys(): try: - f_mul[k_self + k_other] += f_self[k_self]*f_other[k_other] + f_mul[k_self + k_other] += f_self[k_self]*f_other[k_other] except KeyError: - f_mul[k_self + k_other] = f_self[k_self]*f_other[k_other] + f_mul[k_self + k_other] = f_self[k_self]*f_other[k_other] return GM(self.parent(), f_mul) def _lmul_(self, c): From 24e32c68678a4df9da488c84816d814adf2dbe00 Mon Sep 17 00:00:00 2001 From: Gareth Ma Date: Sat, 22 Jul 2023 22:13:27 +0300 Subject: [PATCH 004/216] Apply suggestions from code review --- src/sage/modular/modform/element.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/sage/modular/modform/element.py b/src/sage/modular/modform/element.py index 6e276935c34..27a50922d56 100644 --- a/src/sage/modular/modform/element.py +++ b/src/sage/modular/modform/element.py @@ -2783,7 +2783,7 @@ def _compute_element(self): """ M = self.parent() S = M.cuspidal_subspace() -# return S.find_in_space( self.__E.q_expansion( S.q_expansion_basis()[0].prec() ) ) + [0] * ( M.dimension() - S.dimension() ) + # return S.find_in_space( self.__E.q_expansion( S.q_expansion_basis()[0].prec() ) ) + [0] * ( M.dimension() - S.dimension() ) return vector(S.find_in_space(self.__E.q_expansion(S.sturm_bound())) + [0] * (M.dimension() - S.dimension())) def _compute_q_expansion(self, prec): @@ -3553,16 +3553,17 @@ def _mul_(self, other): sage: (F4 + M(1))^2 4 + 960*q + 66240*q^2 + 1063680*q^3 + 7961280*q^4 + 37560960*q^5 + O(q^6) """ + from collections import defaultdict + GM = self.__class__ f_self = self._forms_dictionary f_other = other._forms_dictionary - f_mul = {} + f_mul = defaultdict(int) + for k_self in f_self.keys(): for k_other in f_other.keys(): - try: - f_mul[k_self + k_other] += f_self[k_self]*f_other[k_other] - except KeyError: - f_mul[k_self + k_other] = f_self[k_self]*f_other[k_other] + f_mul[k_self + k_other] += f_self[k_self] * f_other[k_other] + return GM(self.parent(), f_mul) def _lmul_(self, c): From c2e7ea036aa087fbf010fa2c5449e9662c526f5e Mon Sep 17 00:00:00 2001 From: Gareth Ma Date: Sun, 23 Jul 2023 11:35:28 +0300 Subject: [PATCH 005/216] Revert styling change --- src/sage/modular/modform/element.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/modular/modform/element.py b/src/sage/modular/modform/element.py index 27a50922d56..613582e2bed 100644 --- a/src/sage/modular/modform/element.py +++ b/src/sage/modular/modform/element.py @@ -2783,7 +2783,7 @@ def _compute_element(self): """ M = self.parent() S = M.cuspidal_subspace() - # return S.find_in_space( self.__E.q_expansion( S.q_expansion_basis()[0].prec() ) ) + [0] * ( M.dimension() - S.dimension() ) +# return S.find_in_space( self.__E.q_expansion( S.q_expansion_basis()[0].prec() ) ) + [0] * ( M.dimension() - S.dimension() ) return vector(S.find_in_space(self.__E.q_expansion(S.sturm_bound())) + [0] * (M.dimension() - S.dimension())) def _compute_q_expansion(self, prec): From 8f284bd107074bad8ee4033905c3e5395b591829 Mon Sep 17 00:00:00 2001 From: Sebastian Date: Tue, 12 Sep 2023 08:25:08 +0200 Subject: [PATCH 006/216] push_to_docker_hub initial --- .github/workflows/push_to_docker_hub.yml | 18 +++--------------- docker/Dockerfile | 2 +- 2 files changed, 4 insertions(+), 16 deletions(-) diff --git a/.github/workflows/push_to_docker_hub.yml b/.github/workflows/push_to_docker_hub.yml index af93972b61f..f751f4d5b4b 100644 --- a/.github/workflows/push_to_docker_hub.yml +++ b/.github/workflows/push_to_docker_hub.yml @@ -5,7 +5,6 @@ on: # Allow to run manually branches: - 'develop' - - 'docker_hub_gha' push: tags: # Just create image on pushing a tag @@ -14,6 +13,7 @@ on: jobs: sagemath-dev: name: Build Docker image on target make-build and push to DockerHub sagemath-dev + # target make-build replaces former sagemath-dev, see https://github.com/sagemath/sage/pull/36047 runs-on: ubuntu-latest steps: - name: Checkout @@ -25,7 +25,7 @@ jobs: id: set_tag run: | git fetch --depth=1 origin +refs/tags/*:refs/tags/* - TAG_NAME=$(git tag --sort=v:refname | tail -1) + TAG_NAME=$(git tag --sort=creatordate | tail -1) TAG="sagemath/sagemath-dev:$TAG_NAME" TAG_LIST="$TAG, sagemath/sagemath-dev:develop" TAG_LIST="$TAG" # don't tag develop until meaning of sagemath-dev is clear @@ -41,15 +41,6 @@ jobs: echo "TAG_LIST=$TAG_LIST" >> $GITHUB_ENV if: "!contains(env.TAG_NAME, 'beta') && !contains(env.TAG_NAME, 'rc')" - - name: Check env - run: | - echo ${{ env.TAG_NAME }} - echo ${{ env.TAG }} - echo ${{ env.TAG_LIST }} - - - name: Set up QEMU - uses: docker/setup-qemu-action@v2 - - name: Set up Docker Buildx uses: docker/setup-buildx-action@v2 @@ -84,7 +75,7 @@ jobs: id: set_tag run: | git fetch --depth=1 origin +refs/tags/*:refs/tags/* - TAG_NAME=$(git tag --sort=v:refname | tail -1) + TAG_NAME=$(git tag --sort=creatordate | tail -1) TAG="sagemath/sagemath:$TAG_NAME" TAG_LIST="$TAG, sagemath/sagemath:develop" BASE="sagemath/sagemath-dev:$TAG_NAME" @@ -100,9 +91,6 @@ jobs: echo "TAG_LIST=$TAG_LIST" >> $GITHUB_ENV if: "!contains(env.TAG_NAME, 'beta') && !contains(env.TAG_NAME, 'rc')" - - name: Set up QEMU - uses: docker/setup-qemu-action@v2 - - name: Set up Docker Buildx uses: docker/setup-buildx-action@v2 diff --git a/docker/Dockerfile b/docker/Dockerfile index 6b0ecab4795..359d59dd106 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -75,7 +75,7 @@ ARG MAKE_BUILD=make-build ################################################################################ # Image containing the run-time dependencies for Sage # ################################################################################ -FROM ubuntu:latest as run-time-dependencies +FROM ubuntu:jammy as run-time-dependencies LABEL maintainer="Erik M. Bray , Julian Rüth " # Set sane defaults for common environment variables. ENV LC_ALL C.UTF-8 From 3fa2df7cb850d13f6b0055626151f5c6c717f997 Mon Sep 17 00:00:00 2001 From: Sebastian Date: Tue, 12 Sep 2023 08:26:34 +0200 Subject: [PATCH 007/216] push_to_docker_hub_fixes complete TAG_LIST --- .github/workflows/push_to_docker_hub.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/push_to_docker_hub.yml b/.github/workflows/push_to_docker_hub.yml index f751f4d5b4b..bf404e33fce 100644 --- a/.github/workflows/push_to_docker_hub.yml +++ b/.github/workflows/push_to_docker_hub.yml @@ -37,7 +37,6 @@ jobs: id: upd_tag_list run: | TAG_LIST="${{ env.TAG_LIST }}, sagemath/sagemath-dev:latest" - TAG_LIST="${{ env.TAG_LIST }}" # don't tag latest until meaning of sagemath-dev is clear echo "TAG_LIST=$TAG_LIST" >> $GITHUB_ENV if: "!contains(env.TAG_NAME, 'beta') && !contains(env.TAG_NAME, 'rc')" From abc14c98611b0d539d2be0c8787dc8f7213bd11e Mon Sep 17 00:00:00 2001 From: Sebastian Date: Tue, 12 Sep 2023 08:43:13 +0200 Subject: [PATCH 008/216] ush_to_docker_hub_fixes the missing one --- .github/workflows/push_to_docker_hub.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/push_to_docker_hub.yml b/.github/workflows/push_to_docker_hub.yml index bf404e33fce..394e9550a45 100644 --- a/.github/workflows/push_to_docker_hub.yml +++ b/.github/workflows/push_to_docker_hub.yml @@ -28,7 +28,6 @@ jobs: TAG_NAME=$(git tag --sort=creatordate | tail -1) TAG="sagemath/sagemath-dev:$TAG_NAME" TAG_LIST="$TAG, sagemath/sagemath-dev:develop" - TAG_LIST="$TAG" # don't tag develop until meaning of sagemath-dev is clear echo "TAG_NAME=$TAG_NAME" >> $GITHUB_ENV echo "TAG=$TAG" >> $GITHUB_ENV echo "TAG_LIST=$TAG_LIST" >> $GITHUB_ENV From 9ffa6e709bb337ed9b48af83bf4fbf621e507fc0 Mon Sep 17 00:00:00 2001 From: Sebastian Date: Wed, 20 Sep 2023 18:47:35 +0200 Subject: [PATCH 009/216] dependabot upgrades --- .github/workflows/push_to_docker_hub.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/push_to_docker_hub.yml b/.github/workflows/push_to_docker_hub.yml index f9be690a4dd..77a9f819d70 100644 --- a/.github/workflows/push_to_docker_hub.yml +++ b/.github/workflows/push_to_docker_hub.yml @@ -40,16 +40,16 @@ jobs: if: "!contains(env.TAG_NAME, 'beta') && !contains(env.TAG_NAME, 'rc')" - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v2 + uses: docker/setup-buildx-action@v3 - name: Login to Docker Hub - uses: docker/login-action@v2 + uses: docker/login-action@v3 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - name: Build and push make-build - uses: docker/build-push-action@v4 + uses: docker/build-push-action@v5 with: context: . file: docker/Dockerfile @@ -90,16 +90,16 @@ jobs: if: "!contains(env.TAG_NAME, 'beta') && !contains(env.TAG_NAME, 'rc')" - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v2 + uses: docker/setup-buildx-action@v3 - name: Login to Docker Hub - uses: docker/login-action@v2 + uses: docker/login-action@v3 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - name: Build and push sagemath - uses: docker/build-push-action@v4 + uses: docker/build-push-action@v5 with: context: . file: docker/Dockerfile From 550f5216dd4c1804073c6002e512c776aae3e7bb Mon Sep 17 00:00:00 2001 From: DavidAyotte Date: Thu, 21 Sep 2023 11:44:31 -0600 Subject: [PATCH 010/216] rename FiniteDrinfeldModule into DrinfeldModule_finite --- .../drinfeld_modules/drinfeld_module.py | 20 +++++++++---------- .../finite_drinfeld_module.py | 16 +++++++-------- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/sage/rings/function_field/drinfeld_modules/drinfeld_module.py b/src/sage/rings/function_field/drinfeld_modules/drinfeld_module.py index ed9994f25ac..f6fe2c68e29 100644 --- a/src/sage/rings/function_field/drinfeld_modules/drinfeld_module.py +++ b/src/sage/rings/function_field/drinfeld_modules/drinfeld_module.py @@ -526,7 +526,7 @@ class DrinfeldModule(Parent, UniqueRepresentation): def __classcall_private__(cls, function_ring, gen, name='t'): """ Check input validity and return a ``DrinfeldModule`` or - ``FiniteDrinfeldModule`` object accordingly. + ``DrinfeldModule_finite`` object accordingly. INPUT: @@ -541,24 +541,24 @@ def __classcall_private__(cls, function_ring, gen, name='t'): OUTPUT: - A DrinfeldModule or FiniteDrinfeldModule. + A DrinfeldModule or DrinfeldModule_finite. TESTS:: - sage: from sage.rings.function_field.drinfeld_modules.finite_drinfeld_module import FiniteDrinfeldModule + sage: from sage.rings.function_field.drinfeld_modules.finite_drinfeld_module import DrinfeldModule_finite sage: Fq = GF(25) sage: A. = Fq[] sage: K. = Fq.extension(6) sage: p_root = 2*z12^11 + 2*z12^10 + z12^9 + 3*z12^8 + z12^7 + 2*z12^5 + 2*z12^4 + 3*z12^3 + z12^2 + 2*z12 sage: phi = DrinfeldModule(A, [p_root, z12^3, z12^5]) - sage: isinstance(phi, FiniteDrinfeldModule) + sage: isinstance(phi, DrinfeldModule_finite) True :: sage: K = Frac(A) sage: phi = DrinfeldModule(A, [K(T), 1]) - sage: isinstance(psi, FiniteDrinfeldModule) + sage: isinstance(psi, DrinfeldModule_finite) False """ @@ -624,10 +624,10 @@ def __classcall_private__(cls, function_ring, gen, name='t'): if gen.degree() <= 0: raise ValueError('generator must have positive degree') - # Instantiate the appropriate class + # Instantiate the appropriate class: if base_field.is_finite(): - from sage.rings.function_field.drinfeld_modules.finite_drinfeld_module import FiniteDrinfeldModule - return FiniteDrinfeldModule(gen, category) + from sage.rings.function_field.drinfeld_modules.finite_drinfeld_module import DrinfeldModule_finite + return DrinfeldModule_finite(gen, category) return cls.__classcall__(cls, gen, category) def __init__(self, gen, category): @@ -1601,8 +1601,8 @@ def is_finite(self) -> bool: sage: psi.is_finite() False """ - from sage.rings.function_field.drinfeld_modules.finite_drinfeld_module import FiniteDrinfeldModule - return isinstance(self, FiniteDrinfeldModule) + from sage.rings.function_field.drinfeld_modules.finite_drinfeld_module import DrinfeldModule_finite + return isinstance(self, DrinfeldModule_finite) def j_invariant(self, parameter=None, check=True): r""" diff --git a/src/sage/rings/function_field/drinfeld_modules/finite_drinfeld_module.py b/src/sage/rings/function_field/drinfeld_modules/finite_drinfeld_module.py index e2115323fb8..03fbf08ae3f 100644 --- a/src/sage/rings/function_field/drinfeld_modules/finite_drinfeld_module.py +++ b/src/sage/rings/function_field/drinfeld_modules/finite_drinfeld_module.py @@ -3,7 +3,7 @@ Finite Drinfeld modules This module provides the class -:class:`sage.rings.function_fields.drinfeld_module.finite_drinfeld_module.FiniteDrinfeldModule`, +:class:`sage.rings.function_fields.drinfeld_module.finite_drinfeld_module.DrinfeldModule_finite`, which inherits :class:`sage.rings.function_fields.drinfeld_module.drinfeld_module.DrinfeldModule`. @@ -28,7 +28,7 @@ from sage.rings.function_field.drinfeld_modules.drinfeld_module import DrinfeldModule -class FiniteDrinfeldModule(DrinfeldModule): +class DrinfeldModule_finite(DrinfeldModule): r""" This class implements finite Drinfeld `\mathbb{F}_q[T]`-modules. @@ -42,9 +42,9 @@ class FiniteDrinfeldModule(DrinfeldModule): .. RUBRIC:: Construction: The user does not ever need to directly call - ``FiniteDrinfeldModule`` --- the metaclass ``DrinfeldModule`` is + ``DrinfeldModule_finite`` --- the metaclass ``DrinfeldModule`` is responsible for instantiating ``DrinfeldModule`` or - ``FiniteDrinfeldModule`` depending on the input:: + ``DrinfeldModule_finite`` depending on the input:: sage: Fq = GF(343) sage: A. = Fq[] @@ -57,11 +57,11 @@ class FiniteDrinfeldModule(DrinfeldModule): sage: isinstance(phi, DrinfeldModule) True - sage: from sage.rings.function_field.drinfeld_modules.finite_drinfeld_module import FiniteDrinfeldModule - sage: isinstance(phi, FiniteDrinfeldModule) + sage: from sage.rings.function_field.drinfeld_modules.finite_drinfeld_module import DrinfeldModule_finite + sage: isinstance(phi, DrinfeldModule_finite) True - The user should never use ``FiniteDrinfeldModule`` to test if a + The user should never use ``DrinfeldModule_finite`` to test if a Drinfeld module is finite, but rather the ``is_finite`` method:: sage: phi.is_finite() @@ -148,7 +148,7 @@ def __init__(self, gen, category): True """ # NOTE: There used to be no __init__ here (which was fine). I - # added one to ensure that FiniteDrinfeldModule would always + # added one to ensure that DrinfeldModule_finite would always # have _frobenius_norm and _frobenius_trace attributes. super().__init__(gen, category) self._frobenius_norm = None From bc24795c00b65c0980e50c92047600c54286fd7a Mon Sep 17 00:00:00 2001 From: DavidAyotte Date: Thu, 21 Sep 2023 12:11:15 -0600 Subject: [PATCH 011/216] implement DrinfeldModule_complex --- .../complex_drinfeld_module.py | 231 ++++++++++++++++++ 1 file changed, 231 insertions(+) create mode 100644 src/sage/rings/function_field/drinfeld_modules/complex_drinfeld_module.py diff --git a/src/sage/rings/function_field/drinfeld_modules/complex_drinfeld_module.py b/src/sage/rings/function_field/drinfeld_modules/complex_drinfeld_module.py new file mode 100644 index 00000000000..5c478b15933 --- /dev/null +++ b/src/sage/rings/function_field/drinfeld_modules/complex_drinfeld_module.py @@ -0,0 +1,231 @@ +from .drinfeld_module import DrinfeldModule + +from sage.rings.integer_ring import ZZ + +from sage.misc.cachefunc import cached_method +from sage.misc.lazy_import import lazy_import + +lazy_import('sage.rings.lazy_series_ring', 'LazyPowerSeriesRing') + +class DrinfeldModule_complex(DrinfeldModule): + @cached_method + def _compute_coefficient_exp(self, k): + r""" + Return the `q^k`-th coefficient of the exponential of this Drinfeld module. + + INPUT: + + - ``k`` (integer) -- the index of the coefficient + + TESTS:: + + sage: A = GF(2)['T'] + sage: K. = Frac(A) + sage: phi = DrinfeldModule(A, [T, 1]) + sage: q = A.base_ring().cardinality() + sage: phi._compute_coefficient_exp(0) + 1 + sage: phi._compute_coefficient_exp(1) + 1/(T^2 + T) + sage: phi._compute_coefficient_exp(2) + 1/(T^8 + T^6 + T^5 + T^3) + sage: phi._compute_coefficient_exp(3) + 1/(T^24 + T^20 + T^18 + T^17 + T^14 + T^13 + T^11 + T^7) + """ + k = ZZ(k) + if k.is_zero(): + return self._base.one() + q = self._Fq.cardinality() + c = self._base.zero() + for i in range(k): + j = k - i + c += self._compute_coefficient_exp(i)*self._compute_coefficient_log(j)**(q**i) + return -c + + def exponential(self, name='z'): + r""" + Return the exponential of this Drinfeld module. + + Note that the exponential is only defined when the + `\mathbb{F}_q[T]`-characteristic is zero. + + INPUT: + + - ``name`` (string, default: ``'z'``) -- the name of the + generator of the lazy power series ring. + + OUTPUT: + + A lazy power series over the base field. + + EXAMPLES:: + + sage: A = GF(2)['T'] + sage: K. = Frac(A) + sage: phi = DrinfeldModule(A, [T, 1]) + sage: q = A.base_ring().cardinality() + sage: exp = phi.exponential(); exp + z + ((1/(T^2+T))*z^2) + ((1/(T^8+T^6+T^5+T^3))*z^4) + O(z^8) + + The exponential is returned as a lazy power series, meaning that + any of its coefficients can be computed on demands:: + + sage: exp[2^4] + 1/(T^64 + T^56 + T^52 + ... + T^27 + T^23 + T^15) + sage: exp[2^5] + 1/(T^160 + T^144 + T^136 + ... + T^55 + T^47 + T^31) + + Example in higher rank:: + + sage: A = GF(5)['T'] + sage: K. = Frac(A) + sage: phi = DrinfeldModule(A, [T, T^2, T + T^2 + T^4, 1]) + sage: exp = phi.exponential(); exp + z + ((T/(T^4+4))*z^5) + O(z^8) + + The exponential is the compositional inverse of the logarithm + (see :meth:`logarithm`):: + + sage: log = phi.logarithm(); log + z + ((4*T/(T^4+4))*z^5) + O(z^8) + sage: exp.compose(log) + z + O(z^8) + sage: log.compose(exp) + z + O(z^8) + + TESTS:: + + sage: A = GF(2)['T'] + sage: K. = Frac(A) + sage: phi = DrinfeldModule(A, [T, 1]) + sage: exp = phi.exponential() + sage: exp[2] == 1/(T**q - T) # expected value + True + sage: exp[2^2] == 1/((T**(q**2) - T)*(T**q - T)**q) # expected value + True + sage: exp[2^3] == 1/((T**(q**3) - T)*(T**(q**2) - T)**q*(T**q - T)**(q**2)) # expected value + True + + REFERENCE: + + See section 4.6 of [Gos1998]_ for the definition of the + exponential. + """ + if self.category()._characteristic: + raise ValueError(f"characteristic must be zero (={self.characteristic()})") + L = LazyPowerSeriesRing(self._base, name) + zero = self._base.zero() + q = self._Fq.cardinality() + + def coeff_exp(k): + # Return the k-th coefficient of the exponential. + k = ZZ(k) + if k.is_power_of(q): + return self._compute_coefficient_exp(k.log(q)) + else: + return zero + return L(coeff_exp, valuation=1) + + @cached_method + def _compute_coefficient_log(self, k): + r""" + Return the `q^k`-th coefficient of the logarithm of this Drinfeld module. + + TESTS:: + + sage: A = GF(2)['T'] + sage: K. = Frac(A) + sage: phi = DrinfeldModule(A, [T, 1]) + sage: q = A.base_ring().cardinality() + sage: phi._compute_coefficient_log(0) + 1 + sage: phi._compute_coefficient_log(1) + 1/(T^2 + T) + sage: phi._compute_coefficient_log(2) + 1/(T^6 + T^5 + T^3 + T^2) + sage: phi._compute_coefficient_log(3) + 1/(T^14 + T^13 + T^11 + T^10 + T^7 + T^6 + T^4 + T^3) + """ + k = ZZ(k) + if k.is_zero(): + return self._base.one() + r = self._gen.degree() + T = self._gen[0] + q = self._Fq.cardinality() + c = self._base.zero() + for i in range(k): + j = k - i + if j < r + 1: + c += self._compute_coefficient_log(i)*self._gen[j]**(q**i) + return c/(T - T**(q**k)) + + def logarithm(self, name='z'): + r""" + Return the logarithm of the given Drinfeld module. + + By definition, the logarithm is the compositional inverse of the + exponential (see :meth:`exponential`). Note that the logarithm + is only defined when the `\mathbb{F}_q[T]`-characteristic is + zero. + + INPUT: + + - ``name`` (string, default: ``'z'``) -- the name of the + generator of the lazy power series ring. + + OUTPUT: + + A lazy power series over the base field. + + EXAMPLES:: + + sage: A = GF(2)['T'] + sage: K. = Frac(A) + sage: phi = DrinfeldModule(A, [T, 1]) + sage: log = phi.logarithm(); log + z + ((1/(T^2+T))*z^2) + ((1/(T^6+T^5+T^3+T^2))*z^4) + O(z^8) + + The logarithm is returned as a lazy power series, meaning that + any of its coefficients can be computed on demands:: + + sage: log[2^4] + 1/(T^30 + T^29 + T^27 + ... + T^7 + T^5 + T^4) + sage: log[2^5] + 1/(T^62 + T^61 + T^59 + ... + T^8 + T^6 + T^5) + + Example in higher rank:: + + sage: A = GF(5)['T'] + sage: K. = Frac(A) + sage: phi = DrinfeldModule(A, [T, T^2, T + T^2 + T^4, 1]) + sage: phi.logarithm() + z + ((4*T/(T^4+4))*z^5) + O(z^8) + + TESTS:: + + sage: A = GF(2)['T'] + sage: K. = Frac(A) + sage: phi = DrinfeldModule(A, [T, 1]) + sage: q = 2 + sage: log[2] == -1/((T**q - T)) # expected value + True + sage: log[2**2] == 1/((T**q - T)*(T**(q**2) - T)) # expected value + True + sage: log[2**3] == -1/((T**q - T)*(T**(q**2) - T)*(T**(q**3) - T)) # expected value + True + + """ + if self.category()._characteristic: + raise ValueError(f"characteristic must be zero (={self.characteristic()})") + L = LazyPowerSeriesRing(self._base, name) + zero = self._base.zero() + q = self._Fq.cardinality() + + def coeff_log(k): + # Return the k-th coefficient of the logarithm + k = ZZ(k) + if k.is_power_of(q): + return self._compute_coefficient_log(k.log(q)) + else: + return self._base.zero() + return L(coeff_log, valuation=1) From 62eb3d99531b4d9e152c8cb5b37a9ca1ffc25e5b Mon Sep 17 00:00:00 2001 From: DavidAyotte Date: Thu, 21 Sep 2023 12:40:21 -0600 Subject: [PATCH 012/216] remove exponential and logarithm from DrinfeldModule --- .../drinfeld_modules/drinfeld_module.py | 247 +----------------- 1 file changed, 3 insertions(+), 244 deletions(-) diff --git a/src/sage/rings/function_field/drinfeld_modules/drinfeld_module.py b/src/sage/rings/function_field/drinfeld_modules/drinfeld_module.py index f6fe2c68e29..a318e0027a4 100644 --- a/src/sage/rings/function_field/drinfeld_modules/drinfeld_module.py +++ b/src/sage/rings/function_field/drinfeld_modules/drinfeld_module.py @@ -30,7 +30,6 @@ from sage.categories.drinfeld_modules import DrinfeldModules from sage.categories.homset import Hom from sage.geometry.polyhedron.constructor import Polyhedron -from sage.misc.cachefunc import cached_method from sage.misc.latex import latex from sage.misc.latex import latex_variable_name from sage.misc.lazy_import import lazy_import @@ -46,8 +45,6 @@ from sage.structure.unique_representation import UniqueRepresentation lazy_import('sage.rings.ring_extension', 'RingExtension_generic') -lazy_import('sage.rings.lazy_series_ring', 'LazyPowerSeriesRing') - class DrinfeldModule(Parent, UniqueRepresentation): r""" @@ -628,6 +625,9 @@ def __classcall_private__(cls, function_ring, gen, name='t'): if base_field.is_finite(): from sage.rings.function_field.drinfeld_modules.finite_drinfeld_module import DrinfeldModule_finite return DrinfeldModule_finite(gen, category) + if not category._characteristic: + from .complex_drinfeld_module import DrinfeldModule_complex + return DrinfeldModule_complex(gen, category) return cls.__classcall__(cls, gen, category) def __init__(self, gen, category): @@ -1217,134 +1217,6 @@ def coefficients(self, sparse=True): """ return self._gen.coefficients(sparse=sparse) - @cached_method - def _compute_coefficient_exp(self, k): - r""" - Return the `q^k`-th coefficient of the exponential of this Drinfeld module. - - INPUT: - - - ``k`` (integer) -- the index of the coefficient - - TESTS:: - - sage: A = GF(2)['T'] - sage: K. = Frac(A) - sage: phi = DrinfeldModule(A, [T, 1]) - sage: q = A.base_ring().cardinality() - sage: phi._compute_coefficient_exp(0) - 1 - sage: phi._compute_coefficient_exp(1) - 1/(T^2 + T) - sage: phi._compute_coefficient_exp(2) - 1/(T^8 + T^6 + T^5 + T^3) - sage: phi._compute_coefficient_exp(3) - 1/(T^24 + T^20 + T^18 + T^17 + T^14 + T^13 + T^11 + T^7) - """ - k = ZZ(k) - if k.is_zero(): - return self._base.one() - q = self._Fq.cardinality() - c = self._base.zero() - for i in range(k): - j = k - i - c += self._compute_coefficient_exp(i)*self._compute_coefficient_log(j)**(q**i) - return -c - - def exponential(self, name='z'): - r""" - Return the exponential of this Drinfeld module. - - Note that the exponential is only defined when the - `\mathbb{F}_q[T]`-characteristic is zero. - - INPUT: - - - ``name`` (string, default: ``'z'``) -- the name of the - generator of the lazy power series ring. - - OUTPUT: - - A lazy power series over the base field. - - EXAMPLES:: - - sage: A = GF(2)['T'] - sage: K. = Frac(A) - sage: phi = DrinfeldModule(A, [T, 1]) - sage: q = A.base_ring().cardinality() - sage: exp = phi.exponential(); exp - z + ((1/(T^2+T))*z^2) + ((1/(T^8+T^6+T^5+T^3))*z^4) + O(z^8) - - The exponential is returned as a lazy power series, meaning that - any of its coefficients can be computed on demands:: - - sage: exp[2^4] - 1/(T^64 + T^56 + T^52 + ... + T^27 + T^23 + T^15) - sage: exp[2^5] - 1/(T^160 + T^144 + T^136 + ... + T^55 + T^47 + T^31) - - Example in higher rank:: - - sage: A = GF(5)['T'] - sage: K. = Frac(A) - sage: phi = DrinfeldModule(A, [T, T^2, T + T^2 + T^4, 1]) - sage: exp = phi.exponential(); exp - z + ((T/(T^4+4))*z^5) + O(z^8) - - The exponential is the compositional inverse of the logarithm - (see :meth:`logarithm`):: - - sage: log = phi.logarithm(); log - z + ((4*T/(T^4+4))*z^5) + O(z^8) - sage: exp.compose(log) - z + O(z^8) - sage: log.compose(exp) - z + O(z^8) - - :: - - sage: Fq. = GF(3) - sage: A = Fq['T'] - sage: phi = DrinfeldModule(A, [w, 1]) - sage: phi.exponential() - Traceback (most recent call last): - ... - ValueError: characteristic must be zero (=T + 2) - - TESTS:: - - sage: A = GF(2)['T'] - sage: K. = Frac(A) - sage: phi = DrinfeldModule(A, [T, 1]) - sage: exp = phi.exponential() - sage: exp[2] == 1/(T**q - T) # expected value - True - sage: exp[2^2] == 1/((T**(q**2) - T)*(T**q - T)**q) # expected value - True - sage: exp[2^3] == 1/((T**(q**3) - T)*(T**(q**2) - T)**q*(T**q - T)**(q**2)) # expected value - True - - REFERENCE: - - See section 4.6 of [Gos1998]_ for the definition of the - exponential. - """ - if self.category()._characteristic: - raise ValueError(f"characteristic must be zero (={self.characteristic()})") - L = LazyPowerSeriesRing(self._base, name) - zero = self._base.zero() - q = self._Fq.cardinality() - - def coeff_exp(k): - # Return the k-th coefficient of the exponential. - k = ZZ(k) - if k.is_power_of(q): - return self._compute_coefficient_exp(k.log(q)) - else: - return zero - return L(coeff_exp, valuation=1) - def gen(self): r""" Return the generator of the Drinfeld module. @@ -1889,119 +1761,6 @@ def jk_invariants(self): r = self._gen.degree() # rank of self return {k: self.j_invariant(k) for k in range(1, r)} - @cached_method - def _compute_coefficient_log(self, k): - r""" - Return the `q^k`-th coefficient of the logarithm of this Drinfeld module. - - TESTS:: - - sage: A = GF(2)['T'] - sage: K. = Frac(A) - sage: phi = DrinfeldModule(A, [T, 1]) - sage: q = A.base_ring().cardinality() - sage: phi._compute_coefficient_log(0) - 1 - sage: phi._compute_coefficient_log(1) - 1/(T^2 + T) - sage: phi._compute_coefficient_log(2) - 1/(T^6 + T^5 + T^3 + T^2) - sage: phi._compute_coefficient_log(3) - 1/(T^14 + T^13 + T^11 + T^10 + T^7 + T^6 + T^4 + T^3) - """ - k = ZZ(k) - if k.is_zero(): - return self._base.one() - r = self._gen.degree() - T = self._gen[0] - q = self._Fq.cardinality() - c = self._base.zero() - for i in range(k): - j = k - i - if j < r + 1: - c += self._compute_coefficient_log(i)*self._gen[j]**(q**i) - return c/(T - T**(q**k)) - - def logarithm(self, name='z'): - r""" - Return the logarithm of the given Drinfeld module. - - By definition, the logarithm is the compositional inverse of the - exponential (see :meth:`exponential`). Note that the logarithm - is only defined when the `\mathbb{F}_q[T]`-characteristic is - zero. - - INPUT: - - - ``name`` (string, default: ``'z'``) -- the name of the - generator of the lazy power series ring. - - OUTPUT: - - A lazy power series over the base field. - - EXAMPLES:: - - sage: A = GF(2)['T'] - sage: K. = Frac(A) - sage: phi = DrinfeldModule(A, [T, 1]) - sage: log = phi.logarithm(); log - z + ((1/(T^2+T))*z^2) + ((1/(T^6+T^5+T^3+T^2))*z^4) + O(z^8) - - The logarithm is returned as a lazy power series, meaning that - any of its coefficients can be computed on demands:: - - sage: log[2^4] - 1/(T^30 + T^29 + T^27 + ... + T^7 + T^5 + T^4) - sage: log[2^5] - 1/(T^62 + T^61 + T^59 + ... + T^8 + T^6 + T^5) - - Example in higher rank:: - - sage: A = GF(5)['T'] - sage: K. = Frac(A) - sage: phi = DrinfeldModule(A, [T, T^2, T + T^2 + T^4, 1]) - sage: phi.logarithm() - z + ((4*T/(T^4+4))*z^5) + O(z^8) - - TESTS:: - - sage: A = GF(2)['T'] - sage: K. = Frac(A) - sage: phi = DrinfeldModule(A, [T, 1]) - sage: q = 2 - sage: log[2] == -1/((T**q - T)) # expected value - True - sage: log[2**2] == 1/((T**q - T)*(T**(q**2) - T)) # expected value - True - sage: log[2**3] == -1/((T**q - T)*(T**(q**2) - T)*(T**(q**3) - T)) # expected value - True - - :: - - sage: Fq. = GF(3) - sage: A = Fq['T'] - sage: phi = DrinfeldModule(A, [w, 1]) - sage: phi.logarithm() - Traceback (most recent call last): - ... - ValueError: characteristic must be zero (=T + 2) - """ - if self.category()._characteristic: - raise ValueError(f"characteristic must be zero (={self.characteristic()})") - L = LazyPowerSeriesRing(self._base, name) - zero = self._base.zero() - q = self._Fq.cardinality() - - def coeff_log(k): - # Return the k-th coefficient of the logarithm - k = ZZ(k) - if k.is_power_of(q): - return self._compute_coefficient_log(k.log(q)) - else: - return self._base.zero() - return L(coeff_log, valuation=1) - def morphism(self): r""" Return the morphism object that defines the Drinfeld module. From 489ce741e4eb1c77e7b78a42916eedcf720ed535 Mon Sep 17 00:00:00 2001 From: DavidAyotte Date: Thu, 21 Sep 2023 13:20:29 -0600 Subject: [PATCH 013/216] add some documentation --- .../complex_drinfeld_module.py | 75 ++++++++++++++++++- 1 file changed, 73 insertions(+), 2 deletions(-) diff --git a/src/sage/rings/function_field/drinfeld_modules/complex_drinfeld_module.py b/src/sage/rings/function_field/drinfeld_modules/complex_drinfeld_module.py index 5c478b15933..d004d944336 100644 --- a/src/sage/rings/function_field/drinfeld_modules/complex_drinfeld_module.py +++ b/src/sage/rings/function_field/drinfeld_modules/complex_drinfeld_module.py @@ -1,3 +1,27 @@ +# sage.doctest: optional - sage.rings.finite_rings +r""" +Complex Drinfeld module + +This module provides the class +:class:`sage.rings.function_fields.drinfeld_module.complex_drinfeld_module.DrinfeldModule_complex`, +which inherits +:class:`sage.rings.function_fields.drinfeld_module.drinfeld_module.DrinfeldModule`. + +AUTHORS: + +- David Ayotte (2023-09) +""" + +# ***************************************************************************** +# Copyright (C) 2022 David Ayotte +# +# 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/ +# ***************************************************************************** + from .drinfeld_module import DrinfeldModule from sage.rings.integer_ring import ZZ @@ -8,10 +32,56 @@ lazy_import('sage.rings.lazy_series_ring', 'LazyPowerSeriesRing') class DrinfeldModule_complex(DrinfeldModule): + r""" + This class implements complex Drinfeld `\mathbb{F}_q[T]`-modules. + + A *complex Drinfeld module* is a Drinfeld module whose base field + contains `\mathbb{F}_q(T)` and can be embedded in + `\mathbb{C}_{\infty}`, the completion of an algebraic closure of + `\mathbb{F}_q((1/T))` (the completion of `\mathbb{F}_q(T)`). + + For general definitions and help on Drinfeld modules, see class + :class:`sage.rings.function_fields.drinfeld_module.drinfeld_module.DrinfeldModule`. + + .. RUBRIC:: Construction: + + The user does not ever need to directly call + ``DrinfeldModule_complex`` --- the metaclass ``DrinfeldModule`` is + responsible for instantiating the right class depending on the + input:: + + sage: A = GF(3)['T'] + sage: K. = Frac(A) + sage: phi = DrinfeldModule(A, [T, 1]) + sage: phi + Drinfeld module defined by T |--> t + T + + :: + + sage: isinstance(phi, DrinfeldModule) + True + sage: from sage.rings.function_field.drinfeld_modules.complex_drinfeld_module import DrinfeldModule_complex + sage: isinstance(phi, DrinfeldModule_complex) + True + + .. RUBRIC:: Logarithm and exponential + + It is possible to calculate the logarithm and the exponential of + any complex Drinfeld modules:: + + sage: A = GF(2)['T'] + sage: K. = Frac(A) + sage: phi = DrinfeldModule(A, [T, 1]) + sage: phi.exponential() + z + ((1/(T^2+T))*z^2) + ((1/(T^8+T^6+T^5+T^3))*z^4) + O(z^8) + sage: phi.logarithm() + z + ((1/(T^2+T))*z^2) + ((1/(T^6+T^5+T^3+T^2))*z^4) + O(z^8) + """ @cached_method def _compute_coefficient_exp(self, k): r""" - Return the `q^k`-th coefficient of the exponential of this Drinfeld module. + Return the `q^k`-th coefficient of the exponential of this + Drinfeld module. INPUT: @@ -129,7 +199,8 @@ def coeff_exp(k): @cached_method def _compute_coefficient_log(self, k): r""" - Return the `q^k`-th coefficient of the logarithm of this Drinfeld module. + Return the `q^k`-th coefficient of the logarithm of this + Drinfeld module. TESTS:: From 5c212c97d884e2ece9f63bfb079e487976213f44 Mon Sep 17 00:00:00 2001 From: Michael Orlitzky Date: Fri, 22 Sep 2023 07:50:54 -0400 Subject: [PATCH 014/216] src/sage/misc/persist.pyx: fix a copy/paste error in a docstring The loads() method of the sage unpickler is equivalent to pickle.loads(), not pickle.dumps(). The erroneous docstring was probably copied from the sage unpickler's analogous dumps() method. --- src/sage/misc/persist.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/misc/persist.pyx b/src/sage/misc/persist.pyx index 780fdd40847..6b34b19ef5c 100644 --- a/src/sage/misc/persist.pyx +++ b/src/sage/misc/persist.pyx @@ -887,7 +887,7 @@ class SageUnpickler(_BaseUnpickler): @classmethod def loads(cls, data, **kwargs): """ - Equivalent to :func:`pickle.dumps` but using the + Equivalent to :func:`pickle.loads` but using the :class:`sage.misc.persist.SagePickler`. INPUT: From 68f0c011e4ee8d1064f927e01714c92f6ee5500a Mon Sep 17 00:00:00 2001 From: Michael Orlitzky Date: Fri, 22 Sep 2023 08:16:53 -0400 Subject: [PATCH 015/216] src/sage/misc/persist.pyx: refactor unpickle_all The main goal of this refactorization is to eliminate the inline shell command, passed to os.system(), that runs bunzip2 to decompress a tarball. It has been replaced by python's tarfile module. As a side effect, other compression methods (gzip, xz, et cetera) are now supported. In addition, we have eliminated one use of tmp_dir(), it being replaced by the standard python TemporaryDirectory(). Some of the variable names have also been improved, and a few more sanity checks were added. --- src/sage/misc/persist.pyx | 97 ++++++++++++++++++++++++++++----------- 1 file changed, 71 insertions(+), 26 deletions(-) diff --git a/src/sage/misc/persist.pyx b/src/sage/misc/persist.pyx index 6b34b19ef5c..d224185f47b 100644 --- a/src/sage/misc/persist.pyx +++ b/src/sage/misc/persist.pyx @@ -1091,20 +1091,37 @@ def picklejar(obj, dir=None): fobj.write(stamp) -def unpickle_all(dir, debug=False, run_test_suite=False): +def unpickle_all(target, debug=False, run_test_suite=False): """ - Unpickle all sobj's in the given directory, reporting failures as - they occur. Also printed the number of successes and failure. + Unpickle all ``.sobj`` files in a directory or tar archive. INPUT: - - ``dir`` -- a string; the name of a directory (or of a .tar.bz2 - file that decompresses to a directory) full of pickles. + - ``target`` -- a string; the name of a directory or of a (possibly + compressed) tar archive that contains a single directory of + ``.sobj`` files. The tar archive can be in any format that + python's ``tarfile`` module understands; for example, + ``.tar.gz`` or ``.tar.bz2``. - ``debug`` -- a boolean (default: False) whether to report a stacktrace in case of failure - ``run_test_suite`` -- a boolean (default: False) whether to run ``TestSuite(x).run()`` on the unpickled objects + OUTPUT: + + Typically, two lines are printed: the first reporting the number + of successfully unpickled files, and the second reporting the + number (zero) of failures. If there are failures, however, then a + list of failed files will be printed before either of those lines, + and the failure count will of course be non-zero. + + .. WARNING:: + + You must only pass trusted data to this function, including tar + archives. We use the "data" filter from PEP 706 if possible + while extracting the archive, but even that is not a perfect + solution, and it is only available since python-3.11.4. + EXAMPLES:: sage: dir = tmp_dir() @@ -1113,33 +1130,61 @@ def unpickle_all(dir, debug=False, run_test_suite=False): Successfully unpickled 1 objects. Failed to unpickle 0 objects. """ - i = 0 - j = 0 + import os.path, tarfile + + ok_count = 0 + fail_count = 0 failed = [] tracebacks = [] - # This could use instead Python's tarfile module - if dir.endswith('.tar.bz2'): - # create a temporary directory - from sage.misc.temporary_file import tmp_dir - T = tmp_dir() - # extract tarball to it - os.system('cd "%s"; bunzip2 -c "%s" | tar fx - '%(T, os.path.abspath(dir))) - # Now use the directory in the tarball instead of dir - dir = T + "/" + os.listdir(T)[0] - - for A in sorted(os.listdir(dir)): - if A.endswith('.sobj'): + + if os.path.isfile(target) and tarfile.is_tarfile(target): + import tempfile + with tempfile.TemporaryDirectory() as T: + # Extract the tarball to a temporary directory. The "data" + # filter only became available in python-3.11.4. See PEP + # 706 for background. + with tarfile.open(target) as tf: + if hasattr(tarfile, "data_filter"): + tf.extractall(T, filter="data") + else: + tf.extractall(T) + + # Ensure that the tarball contained exactly one thing, a + # directory. + bad_tarball_msg = "tar archive must contain only a single directory" + contents = os.listdir(T) + if len(contents) != 1: + raise ValueError(bad_tarball_msg) + + dir = os.path.join(T, contents[0]) + if not os.path.isdir(dir): + raise ValueError(bad_tarball_msg) + + # If everything looks OK, start this function over again + # inside the extracted directory. Note: PEP 343 says the + # temporary directory will be cleaned up even when the + # "with" block is exited via a "return" statement. But + # also note that "return" doesn't happen until the + # recursive call to unpickle_all() has completed. + return unpickle_all(dir, debug, run_test_suite) + + if not os.path.isdir(target): + raise ValueError("target is neither a directory nor a tar archive") + + for A in sorted(os.listdir(target)): + f = os.path.join(target, A) + if os.path.isfile(f) and f.endswith('.sobj'): try: - obj = load(os.path.join(dir,A)) + obj = load(f) if run_test_suite: TestSuite(obj).run(catch = False) - i += 1 + ok_count += 1 except Exception: - j += 1 + fail_count += 1 if run_test_suite: - print(" * unpickle failure: TestSuite(load('%s')).run()" % os.path.join(dir, A)) + print(" * unpickle failure: TestSuite(load('%s')).run()" % f) else: - print(" * unpickle failure: load('%s')" % os.path.join(dir, A)) + print(" * unpickle failure: load('%s')" % f) from traceback import print_exc print_exc() failed.append(A) @@ -1148,8 +1193,8 @@ def unpickle_all(dir, debug=False, run_test_suite=False): if failed: print("Failed:\n%s" % ('\n'.join(failed))) - print("Successfully unpickled %s objects." % i) - print("Failed to unpickle %s objects." % j) + print("Successfully unpickled %s objects." % ok_count) + print("Failed to unpickle %s objects." % fail_count) if debug: return tracebacks From 84d046ab95e1b73b5aefdaf737a0d704be3ba8f2 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 23 Sep 2023 09:09:39 -0700 Subject: [PATCH 016/216] build/pkgs/matplotlib: Update to 3.8.0 --- build/pkgs/matplotlib/checksums.ini | 6 +++--- build/pkgs/matplotlib/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/matplotlib/checksums.ini b/build/pkgs/matplotlib/checksums.ini index cbf7302ffb1..6be6d882f3b 100644 --- a/build/pkgs/matplotlib/checksums.ini +++ b/build/pkgs/matplotlib/checksums.ini @@ -1,5 +1,5 @@ tarball=matplotlib-VERSION.tar.gz -sha1=2b78c671f95d52c65154a0dc68372a97582768e5 -md5=77ca9a5b42152c9e2aeca1556f08f5ce -cksum=3201608 +sha1=b3391b48ab0bf91778064ce5b2226ff2a2658d7c +md5=2c70bea4dea84c090a7ecc8e0bb0748f +cksum=1228885956 upstream_url=https://pypi.io/packages/source/m/matplotlib/matplotlib-VERSION.tar.gz diff --git a/build/pkgs/matplotlib/package-version.txt b/build/pkgs/matplotlib/package-version.txt index b72762837ea..19811903a7f 100644 --- a/build/pkgs/matplotlib/package-version.txt +++ b/build/pkgs/matplotlib/package-version.txt @@ -1 +1 @@ -3.6.2 +3.8.0 From 8cec8bfb63f0940f38db5de100028f221852d2f1 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 23 Sep 2023 09:10:14 -0700 Subject: [PATCH 017/216] build/pkgs/pillow: Update to 10.0.1 --- build/pkgs/pillow/checksums.ini | 6 +++--- build/pkgs/pillow/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/pillow/checksums.ini b/build/pkgs/pillow/checksums.ini index 842c4ce3c05..afa97cc028f 100644 --- a/build/pkgs/pillow/checksums.ini +++ b/build/pkgs/pillow/checksums.ini @@ -1,5 +1,5 @@ tarball=Pillow-VERSION.tar.gz -sha1=64243cccc992e4ab60641045775fba65c1cf032b -md5=8deffccb4f402df154fd2fd504d8487c -cksum=2485281093 +sha1=47c1f2179bc7de5e3413feed08f7a859854030c3 +md5=93a0585ab0ee9717a7576129bdabdf93 +cksum=3176045361 upstream_url=https://pypi.io/packages/source/p/pillow/Pillow-VERSION.tar.gz diff --git a/build/pkgs/pillow/package-version.txt b/build/pkgs/pillow/package-version.txt index 37ad5c8b19d..1532420512a 100644 --- a/build/pkgs/pillow/package-version.txt +++ b/build/pkgs/pillow/package-version.txt @@ -1 +1 @@ -9.0.1 +10.0.1 From b966e6419e3bd7bc42e5543c3c182329724e5f7d Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 23 Sep 2023 09:10:27 -0700 Subject: [PATCH 018/216] build/pkgs/contourpy: Update to 1.1.1 --- build/pkgs/contourpy/checksums.ini | 6 +++--- build/pkgs/contourpy/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/contourpy/checksums.ini b/build/pkgs/contourpy/checksums.ini index 2b346a32ccc..f4751b4da06 100644 --- a/build/pkgs/contourpy/checksums.ini +++ b/build/pkgs/contourpy/checksums.ini @@ -1,5 +1,5 @@ tarball=contourpy-VERSION.tar.gz -sha1=f8dac7a79be96e2b8f085f79ba386dba54e99e99 -md5=0ed85863802b1323708b400ae7e7bbd7 -cksum=2680473500 +sha1=eb8520cb7172aa8b957d8ba2d09e8f6d9a068d2a +md5=dd89f11007f39baec1e858ad1f464ea9 +cksum=239770832 upstream_url=https://pypi.io/packages/source/c/contourpy/contourpy-VERSION.tar.gz diff --git a/build/pkgs/contourpy/package-version.txt b/build/pkgs/contourpy/package-version.txt index af0b7ddbffd..524cb55242b 100644 --- a/build/pkgs/contourpy/package-version.txt +++ b/build/pkgs/contourpy/package-version.txt @@ -1 +1 @@ -1.0.6 +1.1.1 From 40ed03b6729520cb81250277e1113158018ced40 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 23 Sep 2023 09:10:35 -0700 Subject: [PATCH 019/216] build/pkgs/fonttools: Update to 4.42.1 --- build/pkgs/fonttools/checksums.ini | 6 +++--- build/pkgs/fonttools/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/fonttools/checksums.ini b/build/pkgs/fonttools/checksums.ini index 1a0ba1454cf..7f0244a5c1a 100644 --- a/build/pkgs/fonttools/checksums.ini +++ b/build/pkgs/fonttools/checksums.ini @@ -1,5 +1,5 @@ tarball=fonttools-VERSION.zip -sha1=8d6f8120ad4b3d00dd92cfea3a2e0b4ae1d72bc7 -md5=c1605575dcc45ef35455ae1d606868b3 -cksum=3346598630 +sha1=5432f0273040b044e8d6465947e3a4c00097bdbf +md5=039956b85e9b84ba53373b0df644f5ad +cksum=3441365368 upstream_url=https://pypi.io/packages/source/f/fonttools/fonttools-VERSION.zip diff --git a/build/pkgs/fonttools/package-version.txt b/build/pkgs/fonttools/package-version.txt index 1f30b28189e..32855ddb789 100644 --- a/build/pkgs/fonttools/package-version.txt +++ b/build/pkgs/fonttools/package-version.txt @@ -1 +1 @@ -4.28.4 +4.42.1 From 81b21bccf4cda5ca8e3ce8a794aa98e9d8598f58 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 23 Sep 2023 09:10:55 -0700 Subject: [PATCH 020/216] build/pkgs/pyparsing: Update to 3.1.1 --- build/pkgs/pyparsing/checksums.ini | 6 +++--- build/pkgs/pyparsing/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/pyparsing/checksums.ini b/build/pkgs/pyparsing/checksums.ini index c002d3a3e65..1c6d7b9b36b 100644 --- a/build/pkgs/pyparsing/checksums.ini +++ b/build/pkgs/pyparsing/checksums.ini @@ -1,5 +1,5 @@ tarball=pyparsing-VERSION.tar.gz -sha1=13f44b5b186a627f2481a8eb0d7aedcd6885a641 -md5=fadc2f3bf5872bf6310576a86c3566e0 -cksum=741417334 +sha1=2e9cf056c36c132f15476dfdd50449d48b48f6a2 +md5=bb8c8c6b8015ca5887ae2c37917ee82e +cksum=513345755 upstream_url=https://files.pythonhosted.org/packages/source/p/pyparsing/pyparsing-VERSION.tar.gz diff --git a/build/pkgs/pyparsing/package-version.txt b/build/pkgs/pyparsing/package-version.txt index 747457c6d22..94ff29cc4de 100644 --- a/build/pkgs/pyparsing/package-version.txt +++ b/build/pkgs/pyparsing/package-version.txt @@ -1 +1 @@ -3.0.9 +3.1.1 From 4066e0f73793e798449e65970b71c77d6c94215c Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 23 Sep 2023 09:11:07 -0700 Subject: [PATCH 021/216] build/pkgs/kiwisolver: Update to 1.4.5 --- build/pkgs/kiwisolver/checksums.ini | 6 +++--- build/pkgs/kiwisolver/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/kiwisolver/checksums.ini b/build/pkgs/kiwisolver/checksums.ini index 3fc15248198..db7ec7448ef 100644 --- a/build/pkgs/kiwisolver/checksums.ini +++ b/build/pkgs/kiwisolver/checksums.ini @@ -1,5 +1,5 @@ tarball=kiwisolver-VERSION.tar.gz -sha1=157556602639eb6cc8546463f56feaa9023e3bcd -md5=73a4e57c33ded99dbe9a5cabca5be04b -cksum=3382585353 +sha1=e5234bdcb7e7b620d47a00da076d50f2b63d8649 +md5=20dea6992699d6be8a563995d7fe0309 +cksum=1731645516 upstream_url=https://files.pythonhosted.org/packages/source/k/kiwisolver/kiwisolver-VERSION.tar.gz diff --git a/build/pkgs/kiwisolver/package-version.txt b/build/pkgs/kiwisolver/package-version.txt index 428b770e3e2..e516bb9d963 100644 --- a/build/pkgs/kiwisolver/package-version.txt +++ b/build/pkgs/kiwisolver/package-version.txt @@ -1 +1 @@ -1.4.3 +1.4.5 From b5f3c9eb15a5ff5d07a8dc5070494fa5fcf2c599 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 23 Sep 2023 09:23:44 -0700 Subject: [PATCH 022/216] build/pkgs/contourpy: Update for meson build system --- build/pkgs/contourpy/dependencies | 2 +- build/pkgs/contourpy/spkg-install.in | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/build/pkgs/contourpy/dependencies b/build/pkgs/contourpy/dependencies index d12b50bf33c..b4f14ae3ca8 100644 --- a/build/pkgs/contourpy/dependencies +++ b/build/pkgs/contourpy/dependencies @@ -1,4 +1,4 @@ - numpy | $(PYTHON_TOOLCHAIN) pybind11 $(PYTHON) + numpy | $(PYTHON_TOOLCHAIN) pybind11 meson_python $(PYTHON) ---------- All lines of this file are ignored except the first. diff --git a/build/pkgs/contourpy/spkg-install.in b/build/pkgs/contourpy/spkg-install.in index 37ac1a53437..70b19a5b415 100644 --- a/build/pkgs/contourpy/spkg-install.in +++ b/build/pkgs/contourpy/spkg-install.in @@ -1,2 +1,6 @@ +# https://github.com/scipy/scipy/issues/16536 - meson breaks when CXX="g++ -std=gnu++11" +export CXX=$(echo "$CXX" | sed 's/-std=[a-z0-9+]*//g') + cd src -sdh_pip_install . +# --no-build-isolation because it has build dep on 'meson', which we don't have as a Python package +sdh_pip_install --no-build-isolation . From c32c24b22fa722133d64baf23de61daf738b813a Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 23 Sep 2023 12:41:44 -0700 Subject: [PATCH 023/216] build/pkgs/fonttools/checksums.ini: Fix up --- build/pkgs/fonttools/checksums.ini | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build/pkgs/fonttools/checksums.ini b/build/pkgs/fonttools/checksums.ini index 7f0244a5c1a..b0aa6d12927 100644 --- a/build/pkgs/fonttools/checksums.ini +++ b/build/pkgs/fonttools/checksums.ini @@ -1,5 +1,5 @@ -tarball=fonttools-VERSION.zip +tarball=fonttools-VERSION.tar.gz sha1=5432f0273040b044e8d6465947e3a4c00097bdbf md5=039956b85e9b84ba53373b0df644f5ad cksum=3441365368 -upstream_url=https://pypi.io/packages/source/f/fonttools/fonttools-VERSION.zip +upstream_url=https://pypi.io/packages/source/f/fonttools/fonttools-VERSION.tar.gz From ed58696789d3082023184f2ca3f47c701b106e16 Mon Sep 17 00:00:00 2001 From: DavidAyotte Date: Sun, 24 Sep 2023 22:56:12 -0400 Subject: [PATCH 024/216] move goss polynomials methods --- .../complex_drinfeld_module.py | 84 ++++++++++++++++ .../drinfeld_modules/drinfeld_module.py | 96 ------------------- 2 files changed, 84 insertions(+), 96 deletions(-) diff --git a/src/sage/rings/function_field/drinfeld_modules/complex_drinfeld_module.py b/src/sage/rings/function_field/drinfeld_modules/complex_drinfeld_module.py index d004d944336..c3e4e7d8866 100644 --- a/src/sage/rings/function_field/drinfeld_modules/complex_drinfeld_module.py +++ b/src/sage/rings/function_field/drinfeld_modules/complex_drinfeld_module.py @@ -300,3 +300,87 @@ def coeff_log(k): else: return self._base.zero() return L(coeff_log, valuation=1) + + @cached_method + def _compute_goss_polynomial(self, n, q, poly_ring, X): + r""" + Utility function for computing the n-th Goss polynomial. + + The user should not call this method directly, but + :meth:`goss_polynomial` instead. + + TESTS:: + + sage: A = GF(2^2)['T'] + sage: K. = Frac(A) + sage: phi = DrinfeldModule(A, [T, T+1, T^2, 1]) + sage: poly_ring = phi.base()['X'] + sage: X = poly_ring.gen() + sage: phi._compute_goss_polynomial(0, 2^2, poly_ring, X) + 0 + sage: phi._compute_goss_polynomial(3, 2^2, poly_ring, X) + X^3 + sage: phi._compute_goss_polynomial(4*3, 2^2, poly_ring, X) + X^12 + sage: phi._compute_goss_polynomial(9, 2^2, poly_ring, X) + X^9 + (1/(T^3 + T^2 + T))*X^6 + (1/(T^6 + T^4 + T^2))*X^3 + + """ + # Trivial cases + if n.is_zero(): + return poly_ring.zero() + if n <= q - 1: + return X**n + if n % q == 0: + return self.goss_polynomial(n // q)**q + # General case + pol = sum(self._compute_coefficient_exp(i+1) + *self._compute_goss_polynomial(n - q**(i+1), q, poly_ring, X) + for i in range(0, (n.log(q).n()).floor())) + return X*(self._compute_goss_polynomial(n - 1, q, poly_ring, X) + pol) + + def goss_polynomial(self, n, var='X'): + r""" + Return the `n`-th Goss polynomial of the Drinfeld module. + + Note that Goss polynomials are only defined for Drinfeld modules + of characteristic zero. + + INPUT: + + - ``n`` (integer) -- the index of the Goss polynomial + + - ``var`` (str, default: ``'X'``) -- the name of polynomial + variable. + + OUTPUT: + + - a univariate polynomial in ``var`` over the base `A`-field. + + EXAMPLES:: + + sage: A = GF(3)['T'] + sage: K. = Frac(A) + sage: phi = DrinfeldModule(A, [T, 1]) # Carlitz module + sage: phi.goss_polynomial(1) + X + sage: phi.goss_polynomial(2) + X^2 + sage: phi.goss_polynomial(4) + X^4 + (1/(T^3 + 2*T))*X^2 + sage: phi.goss_polynomial(5) + X^5 + (2/(T^3 + 2*T))*X^3 + sage: phi.goss_polynomial(10) + X^10 + (1/(T^3 + 2*T))*X^8 + (1/(T^6 + T^4 + T^2))*X^6 + (1/(T^9 + 2*T^3))*X^4 + (1/(T^18 + 2*T^12 + 2*T^10 + T^4))*X^2 + + REFERENCE: + + Section 3 of [Gek1988]_ provides an exposition of Goss + polynomials. + """ + n = ZZ(n) + K = self.base() + poly_ring = K[var] + X = poly_ring.gen() + q = self._Fq.cardinality() + return self._compute_goss_polynomial(n, q, poly_ring, X) diff --git a/src/sage/rings/function_field/drinfeld_modules/drinfeld_module.py b/src/sage/rings/function_field/drinfeld_modules/drinfeld_module.py index 2e7165d75c5..58890f197f8 100644 --- a/src/sage/rings/function_field/drinfeld_modules/drinfeld_module.py +++ b/src/sage/rings/function_field/drinfeld_modules/drinfeld_module.py @@ -1233,102 +1233,6 @@ def gen(self): """ return self._gen - @cached_method - def _compute_goss_polynomial(self, n, q, poly_ring, X): - r""" - Utility function for computing the n-th Goss polynomial. - - The user should not call this method directly, but - :meth:`goss_polynomial` instead. - - TESTS:: - - sage: A = GF(2^2)['T'] - sage: K. = Frac(A) - sage: phi = DrinfeldModule(A, [T, T+1, T^2, 1]) - sage: poly_ring = phi.base()['X'] - sage: X = poly_ring.gen() - sage: phi._compute_goss_polynomial(0, 2^2, poly_ring, X) - 0 - sage: phi._compute_goss_polynomial(3, 2^2, poly_ring, X) - X^3 - sage: phi._compute_goss_polynomial(4*3, 2^2, poly_ring, X) - X^12 - sage: phi._compute_goss_polynomial(9, 2^2, poly_ring, X) - X^9 + (1/(T^3 + T^2 + T))*X^6 + (1/(T^6 + T^4 + T^2))*X^3 - - """ - # Trivial cases - if n.is_zero(): - return poly_ring.zero() - if n <= q - 1: - return X**n - if n % q == 0: - return self.goss_polynomial(n // q)**q - # General case - pol = sum(self._compute_coefficient_exp(i+1) - *self._compute_goss_polynomial(n - q**(i+1), q, poly_ring, X) - for i in range(0, (n.log(q).n()).floor())) - return X*(self._compute_goss_polynomial(n - 1, q, poly_ring, X) + pol) - - def goss_polynomial(self, n, var='X'): - r""" - Return the `n`-th Goss polynomial of the Drinfeld module. - - Note that Goss polynomials are only defined for Drinfeld modules - of characteristic zero. - - INPUT: - - - ``n`` (integer) -- the index of the Goss polynomial - - - ``var`` (str, default: ``'X'``) -- the name of polynomial - variable. - - OUTPUT: - - - a univariate polynomial in ``var`` over the base `A`-field. - - EXAMPLES:: - - sage: A = GF(3)['T'] - sage: K. = Frac(A) - sage: phi = DrinfeldModule(A, [T, 1]) # Carlitz module - sage: phi.goss_polynomial(1) - X - sage: phi.goss_polynomial(2) - X^2 - sage: phi.goss_polynomial(4) - X^4 + (1/(T^3 + 2*T))*X^2 - sage: phi.goss_polynomial(5) - X^5 + (2/(T^3 + 2*T))*X^3 - sage: phi.goss_polynomial(10) - X^10 + (1/(T^3 + 2*T))*X^8 + (1/(T^6 + T^4 + T^2))*X^6 + (1/(T^9 + 2*T^3))*X^4 + (1/(T^18 + 2*T^12 + 2*T^10 + T^4))*X^2 - - TESTS:: - - sage: Fq. = GF(25) - sage: A. = Fq[] - sage: phi = DrinfeldModule(A, [z, 1]) - sage: phi.goss_polynomial(1) - Traceback (most recent call last): - ... - ValueError: characteristic must be zero (=T^2 + 4*T + 2) - - REFERENCE: - - Section 3 of [Gek1988]_ provides an exposition of Goss - polynomials. - """ - if self.category()._characteristic: - raise ValueError(f"characteristic must be zero (={self.characteristic()})") - n = ZZ(n) - K = self.base() - poly_ring = K[var] - X = poly_ring.gen() - q = self._Fq.cardinality() - return self._compute_goss_polynomial(n, q, poly_ring, X) - def height(self): r""" Return the height of the Drinfeld module if the function field From 31e63af22e0582a917b39d8bdafd2574e9b524f3 Mon Sep 17 00:00:00 2001 From: DavidAyotte Date: Sun, 24 Sep 2023 22:57:35 -0400 Subject: [PATCH 025/216] remove unnecessary checks --- .../drinfeld_modules/complex_drinfeld_module.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/sage/rings/function_field/drinfeld_modules/complex_drinfeld_module.py b/src/sage/rings/function_field/drinfeld_modules/complex_drinfeld_module.py index c3e4e7d8866..8cb9e0d285f 100644 --- a/src/sage/rings/function_field/drinfeld_modules/complex_drinfeld_module.py +++ b/src/sage/rings/function_field/drinfeld_modules/complex_drinfeld_module.py @@ -181,8 +181,6 @@ def exponential(self, name='z'): See section 4.6 of [Gos1998]_ for the definition of the exponential. """ - if self.category()._characteristic: - raise ValueError(f"characteristic must be zero (={self.characteristic()})") L = LazyPowerSeriesRing(self._base, name) zero = self._base.zero() q = self._Fq.cardinality() @@ -286,8 +284,6 @@ def logarithm(self, name='z'): True """ - if self.category()._characteristic: - raise ValueError(f"characteristic must be zero (={self.characteristic()})") L = LazyPowerSeriesRing(self._base, name) zero = self._base.zero() q = self._Fq.cardinality() From 6a8cc04eb0e00f2d96739b962c445c0b0ba06a37 Mon Sep 17 00:00:00 2001 From: Sebastian Oehms Date: Mon, 25 Sep 2023 17:37:26 +0200 Subject: [PATCH 026/216] colorings_of_links initial --- src/sage/knots/link.py | 217 +++++++++++++++++++++++++++++++---------- 1 file changed, 165 insertions(+), 52 deletions(-) diff --git a/src/sage/knots/link.py b/src/sage/knots/link.py index a832f695eb1..50aa78272f1 100644 --- a/src/sage/knots/link.py +++ b/src/sage/knots/link.py @@ -3034,7 +3034,7 @@ def links_gould_polynomial(self, varnames='t0, t1'): """ return self.braid().links_gould_polynomial(varnames=varnames) - def _coloring_matrix(self, n): + def _coloring_matrix(self, n=None): r""" Return the coloring matrix of ``self``. @@ -3043,15 +3043,12 @@ def _coloring_matrix(self, n): INPUT: - - ``n`` -- the number of colors to consider - - If ``n`` is not a prime number, it is replaced by the smallest - prime number that is larger than ``n``. + - ``n`` -- the number of colors to consider (if ommitted the + value of the determinant of ``self`` will be taken) OUTPUT: - a matrix over the smallest prime field with cardinality - larger than or equal to ``n``. + a matrix over the residue class ring of integers modulo ``n``. EXAMPLES:: @@ -3062,22 +3059,22 @@ def _coloring_matrix(self, n): [2 2 2] sage: K8 = Knot([[[1, -2, 4, -3, 2, -1, 3, -4]], [1, 1, -1, -1]]) sage: K8._coloring_matrix(4) - [2 0 4 4] - [4 4 2 0] - [0 4 4 2] - [4 2 0 4] + [2 0 3 3] + [3 3 2 0] + [0 3 3 2] + [3 2 0 3] REFERENCES: - :wikipedia:`Fox_n-coloring` """ - from sage.arith.misc import next_prime - from sage.rings.finite_rings.finite_field_constructor import FiniteField - p = next_prime(n - 1) - F = FiniteField(p) + if not n: + n = self.determinant() + from sage.rings.finite_rings.integer_mod_ring import IntegerModRing + R = IntegerModRing(n) arcs = self.arcs(presentation='pd') di = len(arcs) - M = matrix(F, di, di) + M = matrix(R, di, di) crossings = self.pd_code() for i in range(di): crossing = crossings[i] @@ -3091,7 +3088,7 @@ def _coloring_matrix(self, n): M[i, j] -= 1 return M - def is_colorable(self, n): + def is_colorable(self, n=None): r""" Return whether the link is ``n``-colorable. @@ -3104,9 +3101,6 @@ def is_colorable(self, n): - ``n`` -- the number of colors to consider - If ``n`` is not a prime number, it is replaced by the smallest - prime number that is larger than ``n``. - EXAMPLES: We show that the trefoil knot is 3-colorable:: @@ -3121,26 +3115,44 @@ def is_colorable(self, n): sage: K8.is_colorable(3) False + But it is colorable with respect to the value of its determinant:: + + sage: K8.determinant() + 5 + sage: K8.is_colorable() + True + + An examples with non prime determinant:: + + sage: K = Knots().from_table(6, 1) + sage: K.determinant() + 9 + sage: K.is_colorable() + True + REFERENCES: - :wikipedia:`Fox_n-coloring` - Chapter 3 of [Liv1993]_ - .. SEEALSO:: :meth:`colorings` + .. SEEALSO:: :meth:`colorings` and :meth:`coloring_maps` """ - return self._coloring_matrix(n).nullity() > 1 + try: + return self._coloring_matrix(n=n).nullity() > 1 + except NotImplementedError: + M = self._coloring_matrix(n=n) + return M.right_kernel_matrix().dimensions()[0] > 1 - def colorings(self, n): + def colorings(self, n=None): r""" Return the ``n``-colorings of ``self``. INPUT: - - ``n`` -- the number of colors to consider - - If ``n`` is not a prime number, it is replaced by the smallest - prime number that is larger than ``n``. + - ``n`` -- the number of colors to consider (if ommitted the value + of the determinant of ``self`` will be taken). Note that there + are no colorings if n is coprime to the determinant of ``self`` OUTPUT: @@ -3163,28 +3175,128 @@ def colorings(self, n): sage: K.arcs('pd') [[1, 2], [3, 4], [5, 6]] + Note that ``n`` is not the number of different colors to be used. It + can be looked upon the size of the color palette:: + + sage: K = Knots().from_table(9, 15) + sage: cols = K.colorings(13); len(cols) + 156 + sage: max(cols[0].values()) + 12 + sage: max(cols[13].values()) + 9 + REFERENCES: - :wikipedia:`Fox_n-coloring` - Chapter 3 of [Liv1993]_ - .. SEEALSO:: :meth:`is_colorable` + .. SEEALSO:: :meth:`is_colorable` and :meth:`coloring_maps` """ - from sage.arith.misc import next_prime - p = next_prime(n-1) - M = self._coloring_matrix(n) - K = M.right_kernel() + from sage.modules.free_module import FreeModule + M = self._coloring_matrix(n=n) + KM = M.right_kernel_matrix() + F = FreeModule(M.base_ring(), KM.dimensions()[0]) + K = [v*KM for v in F] res = set([]) arcs = self.arcs('pd') for coloring in K: colors = sorted(set(coloring)) - if len(colors) == p: - colors = {b: a for a, b in enumerate(colors)} - res.add(tuple(colors[c] for c in coloring)) + if len(colors) >= 2: + res.add(tuple(coloring)) return [{tuple(arc): col for arc, col in zip(arcs, c)} for c in sorted(res)] + def coloring_maps(self, n=None, finitely_presented=False): + r""" + Return the ``n``-coloring maps of ``self``. These are group + homomorphisms from the fundamental group of ``self`` to the ``n``th + dihedral group. + + INPUT: + + - ``n`` -- the number of colors to consider (if ommitted the value + of the determinant of ``self`` will be taken). Note that there + are no coloring maps if n is coprime to the determinant of ``self`` + + - ``finitely_presented`` (default ``False``) whether to choose the + dihedral groups as finitely presented groups. If not set to ``True`` + they are represented as permutation groups. + + OUTPUT: + + a list of group homomporhisms from the fundamental group of ``self`` + to the ``n``th dihedral group (represented according to the key + argument ``finitely_presented``). + + EXAMPLES:: + + sage: L5a1_1 = Link([[8, 2, 9, 1], [10, 7, 5, 8], [4, 10, 1, 9], + ....: [2, 5, 3, 6], [6, 3, 7, 4]]) + sage: L5a1_1.determinant() + 8 + sage: L5a1_1.coloring_maps(2) + [Group morphism: + From: Finitely presented group < x0, x1, x2, x3, x4 | x4*x1*x0^-1*x1^-1, x0*x4^-1*x3^-1*x4, x2*x0*x1^-1*x0^-1, x1*x3^-1*x2^-1*x3, x3*x2^-1*x4^-1*x2 > + To: Dihedral group of order 4 as a permutation group, + Group morphism: + From: Finitely presented group < x0, x1, x2, x3, x4 | x4*x1*x0^-1*x1^-1, x0*x4^-1*x3^-1*x4, x2*x0*x1^-1*x0^-1, x1*x3^-1*x2^-1*x3, x3*x2^-1*x4^-1*x2 > + To: Dihedral group of order 4 as a permutation group] + sage: col_maps = L5a1_1.coloring_maps(4); len(col_maps) + 12 + sage: col_maps = L5a1_1.coloring_maps(5); len(col_maps) + 0 + sage: col_maps = L5a1_1.coloring_maps(12); len(col_maps) + 36 + sage: col_maps = L5a1_1.coloring_maps(); len(col_maps) + 56 + + applying the map:: + + sage: cm1 = col_maps[0] + sage: gs = L5a1_1.fundamental_group().gens() + sage: d = cm1(gs[0]); d + (1,8)(2,7)(3,6)(4,5) + sage: d.parent() + Dihedral group of order 16 as a permutation group + + using the finitely presented dihedral group:: + + sage: col_maps = L5a1_1.coloring_maps(2, finitely_presented=True) + sage: d = col_maps[0](gs[1]); d + b*a + sage: d.parent() + Finitely presented group < a, b | a^2, b^2, (a*b)^2 > + + REFERENCES: + + - :wikipedia:`Fox_n-coloring` + + - Chapter 3 of [Liv1993]_ + + .. SEEALSO:: :meth:`is_colorable` and :meth:`colorings` + """ + if not n: + n = self.determinant() + + if finitely_presented: + from sage.groups.finitely_presented_named import DihedralPresentation + D = DihedralPresentation(n) + else: + from sage.groups.perm_gps.permgroup_named import DihedralGroup + D = DihedralGroup(n) + + a, b = D.gens() + gr = self.fundamental_group() + cols = self.colorings(n=n) + maps = [] + for c in cols: + t = list(c.values()) + ims = [b*a**i for i in t] + maps.append(gr.hom(ims)) + return maps + def plot(self, gap=0.1, component_gap=0.5, solver=None, color='blue', **kwargs): r""" @@ -3330,12 +3442,12 @@ def plot(self, gap=0.1, component_gap=0.5, solver=None, sphinx_plot(L.plot()) If a coloring is passed, the different arcs are plotted with - the corresponding colors:: + the corresponding colors (see :meth:`colorings`):: sage: B = BraidGroup(4) sage: b = B([1,2,3,1,2,-1,-3,2,3]) sage: L = Link(b) - sage: L.plot(color=L.colorings(3)[0]) + sage: L.plot(color=L.colorings()[0]) Graphics object consisting of ... graphics primitives .. PLOT:: @@ -3344,7 +3456,7 @@ def plot(self, gap=0.1, component_gap=0.5, solver=None, B = BraidGroup(4) b = B([1, 2, 3, 1, 2, -1, -3, 2, 3]) L = Link(b) - sphinx_plot(L.plot(color=L.colorings(3)[0])) + sphinx_plot(L.plot(color=L.colorings()[0])) TESTS: @@ -3365,10 +3477,8 @@ def plot(self, gap=0.1, component_gap=0.5, solver=None, coloring = {int(i): color for i in set(flatten(pd_code))} else: from sage.plot.colors import rainbow - ncolors = len(set(color.values())) + ncolors = max([int(i) for i in color.values()]) + 1 arcs = self.arcs() - if len(color) != len(arcs): - raise ValueError("Number of entries in the color vector must match the number of arcs") rainb = rainbow(ncolors) coloring = {int(i): rainb[color[tuple(j)]] for j in arcs for i in j} comp = self._isolated_components() @@ -3914,10 +4024,11 @@ def get_knotinfo(self, mirror_version=True, unique=True): sage: l.get_knotinfo(unique=False) # optional - database_knotinfo [(, False), (, False)] - sage: k11 = KnotInfo.K11n_82.link() # optional - database_knotinfo - sage: k11m = k11.mirror_image() # optional - database_knotinfo - sage: k11mr = k11m.reverse() # optional - database_knotinfo - sage: k11mr.get_knotinfo() # optional - database_knotinfo + sage: # optional - database_knotinfo + sage: k11 = KnotInfo.K11n_82.link() + sage: k11m = k11.mirror_image() + sage: k11mr = k11m.reverse() + sage: k11mr.get_knotinfo() Traceback (most recent call last): ... NotImplementedError: mirror type of this link cannot be uniquely determined @@ -4016,18 +4127,20 @@ def get_knotinfo(self, mirror_version=True, unique=True): Another pair of confusion (see the corresponding `Warning `__):: - sage: Ks10_86 = snappy.Link('10_86') # optional - snappy - sage: Ks10_83 = snappy.Link('10_83') # optional - snappy - sage: Ks10_86.sage_link().get_knotinfo() # optional - snappy + sage: # optional - snappy + sage: Ks10_86 = snappy.Link('10_86') + sage: Ks10_83 = snappy.Link('10_83') + sage: Ks10_86.sage_link().get_knotinfo() (, True) - sage: Ks10_83.sage_link().get_knotinfo() # optional - snappy + sage: Ks10_83.sage_link().get_knotinfo() (, False) TESTS:: - sage: L = KnotInfo.L10a171_1_1_0 # optional - database_knotinfo - sage: l = L.link(L.items.braid_notation) # optional - database_knotinfo - sage: l.get_knotinfo(unique=False) # optional - database_knotinfo + sage: # optional - database_knotinfo + sage: L = KnotInfo.L10a171_1_1_0 + sage: l = L.link(L.items.braid_notation) + sage: l.get_knotinfo(unique=False) [(, True), (, True), (, False), From 8b8c802363ce9a5747134732ed5e60e99dd42130 Mon Sep 17 00:00:00 2001 From: Sebastian Date: Tue, 26 Sep 2023 21:34:57 +0200 Subject: [PATCH 027/216] colorings_of_links fix docstring formatting --- src/sage/knots/link.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/knots/link.py b/src/sage/knots/link.py index 50aa78272f1..1ca2c790815 100644 --- a/src/sage/knots/link.py +++ b/src/sage/knots/link.py @@ -3211,8 +3211,8 @@ def colorings(self, n=None): def coloring_maps(self, n=None, finitely_presented=False): r""" Return the ``n``-coloring maps of ``self``. These are group - homomorphisms from the fundamental group of ``self`` to the ``n``th - dihedral group. + homomorphisms from the fundamental group of ``self`` to the + ``n``-th dihedral group. INPUT: From 1d88e0e2ec76781a18cdb4f54e385a5741353b2b Mon Sep 17 00:00:00 2001 From: Sebastian Date: Wed, 27 Sep 2023 07:28:48 +0200 Subject: [PATCH 028/216] colorings_of_links fix one more docstring formatting --- 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 1ca2c790815..b88cdf7c5e9 100644 --- a/src/sage/knots/link.py +++ b/src/sage/knots/link.py @@ -3227,7 +3227,7 @@ def coloring_maps(self, n=None, finitely_presented=False): OUTPUT: a list of group homomporhisms from the fundamental group of ``self`` - to the ``n``th dihedral group (represented according to the key + to the ``n``-th dihedral group (represented according to the key argument ``finitely_presented``). EXAMPLES:: From 70b2d0b0f83b6d6751b25bd2f42c3d83a65f0d3a Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 29 Sep 2023 20:49:18 -0700 Subject: [PATCH 029/216] build/bin/sage-dist-helpers (sdh_pip_install): Handle --config-settings --- build/bin/sage-dist-helpers | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/build/bin/sage-dist-helpers b/build/bin/sage-dist-helpers index 67a2201d31f..6f330deed22 100644 --- a/build/bin/sage-dist-helpers +++ b/build/bin/sage-dist-helpers @@ -242,6 +242,7 @@ sdh_pip_install() { mkdir -p dist rm -f dist/*.whl install_options="" + build_options="" # pip has --no-build-isolation but no flag that turns the default back on... build_isolation_option="--find-links=$SAGE_SPKG_WHEELS" while [ $# -gt 0 ]; do @@ -260,13 +261,18 @@ sdh_pip_install() { --no-deps) install_options="$install_options $1" ;; + -C|--config-settings) + build_options="$build_options $1" + shift + build_options="$build_options $1" + ;; *) break ;; esac shift done - if python3 -m pip wheel --wheel-dir=dist --verbose --no-deps --no-index --isolated --ignore-requires-python $build_isolation_option "$@"; then + if python3 -m pip wheel --wheel-dir=dist --verbose --no-deps --no-index --isolated --ignore-requires-python $build_isolation_option $build_options "$@"; then : # successful else case $build_isolation_option in @@ -277,7 +283,7 @@ sdh_pip_install() { echo >&2 "Warning: building with \"python3 -m pip wheel --wheel-dir=dist --verbose --no-deps --no-index --isolated --ignore-requires-python $build_isolation_option\" failed." build_isolation_option="--no-build-isolation --no-binary :all:" echo >&2 "Retrying with \"python3 -m pip wheel --wheel-dir=dist --verbose --no-deps --no-index --isolated --ignore-requires-python $build_isolation_option\"." - if python3 -m pip wheel --wheel-dir=dist --verbose --no-deps --no-index --isolated --ignore-requires-python $build_isolation_option "$@"; then + if python3 -m pip wheel --wheel-dir=dist --verbose --no-deps --no-index --isolated --ignore-requires-python $build_isolation_option $build_options "$@"; then echo >&2 "Warning: Wheel building needed to use \"$build_isolation_option\" to succeed. This means that a dependencies file in build/pkgs/ needs to be updated. Please report this to sage-devel@googlegroups.com, including the build log of this package." else sdh_die "Error building a wheel for $PKG_NAME" From 00f6b00309a4c06ef12b4a998a8397e09a9f2751 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 29 Sep 2023 20:49:51 -0700 Subject: [PATCH 030/216] build/pkgs/pillow/spkg-install.in: Update to new config format --- build/pkgs/pillow/spkg-install.in | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/build/pkgs/pillow/spkg-install.in b/build/pkgs/pillow/spkg-install.in index dade6b99a5c..e76b30f7383 100644 --- a/build/pkgs/pillow/spkg-install.in +++ b/build/pkgs/pillow/spkg-install.in @@ -1,20 +1,11 @@ cd src -# Delete old version -rm -rf \ - "$SAGE_LOCAL"/lib/python*/site-packages/PIL \ - "$SAGE_LOCAL"/lib/python*/site-packages/PIL-*.egg* \ - "$SAGE_LOCAL"/lib/python*/site-packages/Pillow-*.egg* - if [ "$CONDA_PREFIX" != "" ]; then # Quoted quotes so that whitespace in CONDA_PREFIX works correctly. # Below we run the command line through eval. - PILLOW_BUILD_EXT="$PILLOW_BUILD_EXT --disable-platform-guessing -I\"$CONDA_PREFIX/include\" -L\"$CONDA_PREFIX/lib\"" + PILLOW_CONFIG_SETTINGS="$PILLOW_CONFIG_SETTINGS -C platform-guessing=disable" fi -PILLOW_BUILD_EXT="--debug --disable-jpeg $PILLOW_BUILD_EXT" +PILLOW_CONFIG_SETTINGS="-C debug=true -C jpeg=disable $PILLOW_CONFIG_SETTINGS" -# Note: Avoid shared libraries inside egg files, Trac #19467 -eval sdh_pip_install \ - $(eval sdh_prefix_args "--build-option" build_ext $PILLOW_BUILD_EXT) \ - . +eval sdh_pip_install $PILLOW_CONFIG_SETTINGS . From 73e5b3f95941f4c34d0a8f8915b46f71d344da2b Mon Sep 17 00:00:00 2001 From: sheerluck Date: Tue, 3 Oct 2023 09:01:36 +0300 Subject: [PATCH 031/216] fix for ecl in distros/gentoo.txt --- build/pkgs/ecl/distros/gentoo.txt | 2 +- build/pkgs/maxima/distros/gentoo.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/build/pkgs/ecl/distros/gentoo.txt b/build/pkgs/ecl/distros/gentoo.txt index 416fa20614c..5a1844851af 100644 --- a/build/pkgs/ecl/distros/gentoo.txt +++ b/build/pkgs/ecl/distros/gentoo.txt @@ -1 +1 @@ -dev-lisp/ecls +dev-lisp/ecl diff --git a/build/pkgs/maxima/distros/gentoo.txt b/build/pkgs/maxima/distros/gentoo.txt index 85fb33f1610..588557a2eb9 100644 --- a/build/pkgs/maxima/distros/gentoo.txt +++ b/build/pkgs/maxima/distros/gentoo.txt @@ -1,2 +1,2 @@ -sci-mathematics/maxima[ecls] +sci-mathematics/maxima[ecl] From 2c2c1e166a163d6237e59702331cafff0b822e89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Tue, 3 Oct 2023 20:22:42 +0200 Subject: [PATCH 032/216] a few details in combinat, as suggested by ruff --- src/sage/combinat/bijectionist.py | 26 +++++++++---------- .../combinat/binary_recurrence_sequences.py | 12 ++++----- .../cluster_algebra_quiver/cluster_seed.py | 2 +- src/sage/combinat/composition_tableau.py | 2 +- src/sage/combinat/crystals/crystals.py | 2 +- src/sage/combinat/e_one_star.py | 2 +- src/sage/combinat/matrices/hadamard_matrix.py | 4 +-- src/sage/combinat/partition.py | 4 +-- .../root_lattice_realization_algebras.py | 6 ++--- src/sage/combinat/skew_partition.py | 4 +-- src/sage/combinat/words/abstract_word.py | 4 +-- 11 files changed, 34 insertions(+), 34 deletions(-) diff --git a/src/sage/combinat/bijectionist.py b/src/sage/combinat/bijectionist.py index 68d1f322e9f..891f01c8eae 100644 --- a/src/sage/combinat/bijectionist.py +++ b/src/sage/combinat/bijectionist.py @@ -1671,7 +1671,7 @@ def different_values(p1, p2): def merge_until_split(): for tZ in list(multiple_preimages): tP = multiple_preimages[tZ] - for i2 in range(len(tP)-1, -1, -1): + for i2 in range(len(tP) - 1, -1, -1): for i1 in range(i2): try: solution = different_values(tP[i1], tP[i2]) @@ -1766,17 +1766,16 @@ def possible_values(self, p=None, optimal=False): {'a': {0, 1}, 'b': {0, 1}} sage: bij.possible_values(p="a", optimal=True) {'a': set(), 'b': set()} - """ # convert input to set of block representatives blocks = set() if p in self._A: blocks.add(self._P.find(p)) - elif type(p) is list: # TODO: this looks very brittle + elif isinstance(p, list): # TODO: this looks very brittle for p1 in p: if p1 in self._A: blocks.add(self._P.find(p1)) - elif type(p1) is list: + elif isinstance(p1, list): for p2 in p1: blocks.add(self._P.find(p2)) @@ -2083,7 +2082,7 @@ def minimal_subdistributions_blocks_iterator(self): minimal_subdistribution.add_constraint(sum(D[p] for p in P) >= 1) for p in P: minimal_subdistribution.add_constraint(D[p] <= len(self._P.root_to_elements_dict()[p])) - minimal_subdistribution.add_constraint(X[p]*len(self._P.root_to_elements_dict()[p]) >= D[p] >= X[p]) + minimal_subdistribution.add_constraint(X[p] * len(self._P.root_to_elements_dict()[p]) >= D[p] >= X[p]) def add_counter_example_constraint(s): for v in self._Z: @@ -2175,7 +2174,7 @@ def _preprocess_intertwining_relations(self): P = self._P images = defaultdict(set) # A^k -> A, a_1,...,a_k +-> {pi(a_1,...,a_k) for all pi} for pi_rho in self._pi_rho: - for a_tuple in itertools.product(*([A]*pi_rho.numargs)): + for a_tuple in itertools.product(*([A] * pi_rho.numargs)): if pi_rho.domain is not None and not pi_rho.domain(*a_tuple): continue a = pi_rho.pi(*a_tuple) @@ -2565,9 +2564,9 @@ def show(self, variables=True): varid_name[i] = default_name for i, (lb, (indices, values), ub) in enumerate(self.milp.constraints()): if b.row_name(i): - print(" "+b.row_name(i)+":", end=" ") + print(" " + b.row_name(i) + ":", end=" ") if lb is not None: - print(str(ZZ(lb))+" <=", end=" ") + print(str(ZZ(lb)) + " <=", end=" ") first = True for j, c in sorted(zip(indices, values)): c = ZZ(c) @@ -2581,7 +2580,7 @@ def show(self, variables=True): + varid_name[j]), end=" ") first = False # Upper bound - print("<= "+str(ZZ(ub)) if ub is not None else "") + print("<= " + str(ZZ(ub)) if ub is not None else "") if variables: print("Variables are:") @@ -2863,8 +2862,8 @@ def add_distribution_constraints(self): Z_dict = {z: i for i, z in enumerate(Z)} zero = self.milp.linear_functions_parent().zero() for tA, tZ in self._bijectionist._elements_distributions: - tA_sum = [zero]*len(Z_dict) - tZ_sum = [zero]*len(Z_dict) + tA_sum = [zero] * len(Z_dict) + tZ_sum = [zero] * len(Z_dict) for a in tA: p = self._bijectionist._P.find(a) for z in self._bijectionist._possible_block_values[p]: @@ -3045,12 +3044,13 @@ def add_homomesic_constraints(self): tZ = self._bijectionist._possible_block_values def sum_q(q): - return sum(sum(z*self._x[P.find(a), z] for z in tZ[P.find(a)]) + return sum(sum(z * self._x[P.find(a), z] for z in tZ[P.find(a)]) for a in q) q0 = Q[0] v0 = sum_q(q0) for q in Q[1:]: - self.milp.add_constraint(len(q0)*sum_q(q) == len(q)*v0, name=f"h: ({q})~({q0})") + self.milp.add_constraint(len(q0) * sum_q(q) == len(q) * v0, + name=f"h: ({q})~({q0})") def _invert_dict(d): diff --git a/src/sage/combinat/binary_recurrence_sequences.py b/src/sage/combinat/binary_recurrence_sequences.py index 9527c512360..62181aeba23 100644 --- a/src/sage/combinat/binary_recurrence_sequences.py +++ b/src/sage/combinat/binary_recurrence_sequences.py @@ -692,7 +692,7 @@ def pthpowers(self, p, Bound): #gather congruence data for the sequence mod ell, which will be mod period(ell) = modu cong1, modu = _find_cong1(p, self, ell) - CongNew = [] #makes a new list from cong that is now mod M = lcm(M1, modu) instead of M1 + CongNew = [] # makes a new list from cong that is now mod M = lcm(M1, modu) instead of M1 M = lcm(M1, modu) for k in range(M // M1): for i in cong: @@ -701,18 +701,18 @@ def pthpowers(self, p, Bound): M1 = M - killed_something = False #keeps track of when cong1 can rule out a congruence in cong + killed_something = False # keeps track of when cong1 can rule out a congruence in cong - #CRT by hand to gain speed + # CRT by hand to gain speed for i in list(cong): - if not (i % modu in cong1): #congruence in cong is inconsistent with any in cong1 - cong.remove(i) #remove that congruence + if (i % modu) not in cong1: # congruence in cong is inconsistent with any in cong1 + cong.remove(i) # remove that congruence killed_something = True if M1 == M2: if not killed_something: tries += 1 - if tries == 2: #try twice to rule out congruences + if tries == 2: # try twice to rule out congruences cong = list(cong) qqold = qq qq = next_prime_power(qq) diff --git a/src/sage/combinat/cluster_algebra_quiver/cluster_seed.py b/src/sage/combinat/cluster_algebra_quiver/cluster_seed.py index a67af5739ce..2bb5c55d9e5 100644 --- a/src/sage/combinat/cluster_algebra_quiver/cluster_seed.py +++ b/src/sage/combinat/cluster_algebra_quiver/cluster_seed.py @@ -4345,7 +4345,7 @@ def oriented_exchange_graph(self): j = i.mutate(k, inplace=False) Varj = tuple(sorted(j.cluster())) covers.append((Vari, Varj)) - if not(Varj in known_clusters): + if Varj not in known_clusters: known_clusters += [Varj] stack.append(j) diff --git a/src/sage/combinat/composition_tableau.py b/src/sage/combinat/composition_tableau.py index 5827c05461b..18b1b85966c 100644 --- a/src/sage/combinat/composition_tableau.py +++ b/src/sage/combinat/composition_tableau.py @@ -95,7 +95,7 @@ def __init__(self, parent, t): if not all(isinstance(row, list) for row in t): raise ValueError("a composition tableau must be a list of lists") - if not [len(r) for r in t] in Compositions(): + if any(not r for r in t): raise ValueError("a composition tableau must be a list of non-empty lists") # Verify rows weakly decrease from left to right diff --git a/src/sage/combinat/crystals/crystals.py b/src/sage/combinat/crystals/crystals.py index dbc2e9a211f..4ae39ac37c1 100644 --- a/src/sage/combinat/crystals/crystals.py +++ b/src/sage/combinat/crystals/crystals.py @@ -245,7 +245,7 @@ def _rec(self, x, state): for j in self._index_set: if j == i: break - if not y.e(j) is None: + if y.e(j) is not None: hasParent = True break if hasParent: diff --git a/src/sage/combinat/e_one_star.py b/src/sage/combinat/e_one_star.py index cb6e5607931..f7f8944a399 100644 --- a/src/sage/combinat/e_one_star.py +++ b/src/sage/combinat/e_one_star.py @@ -1418,7 +1418,7 @@ def __init__(self, sigma, method='suffix'): raise ValueError("the substitution (%s) must be unimodular" % sigma) first_letter = sigma.codomain().alphabet()[0] - if not (first_letter in ZZ) or (first_letter < 1): + if first_letter not in ZZ or first_letter < 1: raise ValueError("the substitution (%s) must be defined on positive integers" % sigma) self._sigma = WordMorphism(sigma) diff --git a/src/sage/combinat/matrices/hadamard_matrix.py b/src/sage/combinat/matrices/hadamard_matrix.py index 6174fe3df50..200a78a550d 100644 --- a/src/sage/combinat/matrices/hadamard_matrix.py +++ b/src/sage/combinat/matrices/hadamard_matrix.py @@ -993,12 +993,12 @@ def hadamard_matrix_from_sds(n, existence=False, check=True): sage: hadamard_matrix_from_sds(14) Traceback (most recent call last): ... - ValueError: n must be a positive multiple of four. + ValueError: n must be a positive multiple of four """ from sage.combinat.designs.difference_family import supplementary_difference_set_hadamard if n <= 0 or n % 4 != 0: - raise ValueError(f'n must be a positive multiple of four.') + raise ValueError('n must be a positive multiple of four') t = n // 4 if existence: diff --git a/src/sage/combinat/partition.py b/src/sage/combinat/partition.py index 3c5535c88c1..1d0449b3d1e 100644 --- a/src/sage/combinat/partition.py +++ b/src/sage/combinat/partition.py @@ -4201,8 +4201,8 @@ def zero_one_sequence(self): sage: all(Partitions().from_zero_one(mu.zero_one_sequence()) == mu for n in range(10) for mu in Partitions(n)) True """ - tmp = [self[i]-i for i in range(len(self))] - return ([Integer(not (i in tmp)) for i in range(-len(self)+1,self.get_part(0)+1)]) + tmp = [self[i] - i for i in range(len(self))] + return [Integer(i not in tmp) for i in range(-len(self) + 1, self.get_part(0) + 1)] def core(self, length): r""" diff --git a/src/sage/combinat/root_system/root_lattice_realization_algebras.py b/src/sage/combinat/root_system/root_lattice_realization_algebras.py index 62bfff6060a..30251e983a7 100644 --- a/src/sage/combinat/root_system/root_lattice_realization_algebras.py +++ b/src/sage/combinat/root_system/root_lattice_realization_algebras.py @@ -313,14 +313,14 @@ def _test_demazure_operators(self, **options): alphacheck = L.simple_coroots() s = L.simple_reflections() for i in self.cartan_type().index_set(): - emalphai = self.monomial(-alpha[i]) # X^{-\alpha_i} + emalphai = self.monomial(-alpha[i]) # X^{-\alpha_i} for weight in L.some_elements(): - if not weight.scalar(alphacheck[i]) in ZZ: + if weight.scalar(alphacheck[i]) not in ZZ: # Demazure operators are not defined in this case continue x = self.monomial(weight) result = pi[i](x) - tester.assertEqual(result * (self.one()-emalphai), + tester.assertEqual(result * (self.one() - emalphai), x - emalphai * x.map_support(s[i])) except ImportError: pass diff --git a/src/sage/combinat/skew_partition.py b/src/sage/combinat/skew_partition.py index 92979d13a82..a897c993460 100644 --- a/src/sage/combinat/skew_partition.py +++ b/src/sage/combinat/skew_partition.py @@ -1005,11 +1005,11 @@ def frobenius_rank(self): True """ N = len(self[0]) - mu_betas = [x - j for (j, x) in enumerate(self[1])] + mu_betas = [x - j for j, x in enumerate(self[1])] mu_betas.extend([- j for j in range(len(self[1]), N)]) res = 0 for i, x in enumerate(self[0]): - if not x - i in mu_betas: + if (x - i) not in mu_betas: res += 1 return res diff --git a/src/sage/combinat/words/abstract_word.py b/src/sage/combinat/words/abstract_word.py index 1488d8e7271..77174089f78 100644 --- a/src/sage/combinat/words/abstract_word.py +++ b/src/sage/combinat/words/abstract_word.py @@ -632,7 +632,7 @@ def _to_integer_iterator(self, use_parent_alphabet=False): """ from sage.combinat.words.words import FiniteWords, InfiniteWords if use_parent_alphabet and\ - isinstance(self.parent(), (FiniteWords, InfiniteWords)): + isinstance(self.parent(), (FiniteWords, InfiniteWords)): A = self.parent().alphabet() for letter in self: yield A.rank(letter) @@ -641,7 +641,7 @@ def _to_integer_iterator(self, use_parent_alphabet=False): mapping = {} next_value = 0 for letter in self: - if not(letter in mapping): + if letter not in mapping: mapping[letter] = next_value next_value += 1 yield mapping[letter] From 47cbfa7207745bddeb8f6904c3829883dca4cff7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Tue, 3 Oct 2023 20:36:44 +0200 Subject: [PATCH 033/216] another fix --- src/sage/combinat/designs/database.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/sage/combinat/designs/database.py b/src/sage/combinat/designs/database.py index d06578ccc22..bbaf439e628 100644 --- a/src/sage/combinat/designs/database.py +++ b/src/sage/combinat/designs/database.py @@ -2504,7 +2504,6 @@ def QDM_57_9_1_1_8(): (3 ,6 ) : ((0,1,3,7), _ref_Handbook), (3 ,26) : ((0,1,3,8), _ref_Handbook), (3 ,32) : ((0,1,3,9), _ref_Handbook), - (3 ,6 ) : ((0,1,3,7), _ref_Handbook), (3 ,14) : ((0,1,4,13), _ref_Handbook), (3 ,24) : ((0,1,3,15), _ref_Handbook), (3 ,34) : ((0,1,3,7), _ref_Handbook), From e918f8eb2003003aeca7c5741010d60060286ec7 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 3 Oct 2023 22:52:09 -0700 Subject: [PATCH 034/216] build/pkgs/singular: Update to 4.3.2p8 --- build/pkgs/singular/checksums.ini | 6 +++--- build/pkgs/singular/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/singular/checksums.ini b/build/pkgs/singular/checksums.ini index 1101fc55700..40ba7b3153f 100644 --- a/build/pkgs/singular/checksums.ini +++ b/build/pkgs/singular/checksums.ini @@ -1,5 +1,5 @@ tarball=singular-VERSION.tar.gz -sha1=df1997f412580f2073295aba569bb955ad227317 -md5=50349213e206a18cdaa1bc410dde7ea4 -cksum=376854707 +sha1=0dd736f26935ed72999bb9a4bbb98c6df18ab9ea +md5=0f9368193bad9a0c3dc84545b2404761 +cksum=1698641648 upstream_url=ftp://jim.mathematik.uni-kl.de/pub/Math/Singular/SOURCES/4-3-2/singular-VERSION.tar.gz diff --git a/build/pkgs/singular/package-version.txt b/build/pkgs/singular/package-version.txt index 9f1bf008217..7801ff9a882 100644 --- a/build/pkgs/singular/package-version.txt +++ b/build/pkgs/singular/package-version.txt @@ -1 +1 @@ -4.3.2p7 +4.3.2p8 From c1b777983069ab7cc619eceb570ed8f16a4de7f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Fri, 22 Sep 2023 08:41:40 +0200 Subject: [PATCH 035/216] tentative of random subset --- src/sage/matrix/special.py | 117 +++++++++++++++++++------------------ 1 file changed, 60 insertions(+), 57 deletions(-) diff --git a/src/sage/matrix/special.py b/src/sage/matrix/special.py index 41b64965ca3..54b1da99dd5 100644 --- a/src/sage/matrix/special.py +++ b/src/sage/matrix/special.py @@ -62,6 +62,7 @@ # (at your option) any later version. # https://www.gnu.org/licenses/ # **************************************************************************** +from copy import copy from sage.rings.ring import is_Ring import sage.matrix.matrix_space as matrix_space @@ -72,9 +73,8 @@ from sage.rings.rational_field import QQ from sage.rings.integer import Integer from sage.misc.misc_c import running_total -from copy import copy +from sage.misc.prandom import randint, shuffle from .constructor import matrix - import sage.categories.pushout @@ -2473,104 +2473,107 @@ def random_rref_matrix(parent, num_pivots): TESTS: + Rank zero:: + + sage: random_matrix(QQ, 1, 1, algorithm='echelon_form', num_pivots=0) + [0] + Rank of a matrix must be an integer. :: sage: random_matrix(QQ, 120, 56, algorithm='echelon_form', num_pivots=61/2) Traceback (most recent call last): ... - TypeError: the number of pivots must be an integer. + TypeError: the number of pivots must be an integer Matrices must be generated over exact fields. :: sage: random_matrix(RR, 40, 88, algorithm='echelon_form', num_pivots=39) Traceback (most recent call last): ... - TypeError: the base ring must be exact. + TypeError: the base ring must be exact Matrices must have the number of pivot columns be less than or equal to the number of rows. :: - sage: C=random_matrix(ZZ, 6,4, algorithm='echelon_form', num_pivots=7); C + sage: C = random_matrix(ZZ, 6,4, algorithm='echelon_form', num_pivots=7); C Traceback (most recent call last): ... - ValueError: number of pivots cannot exceed the number of rows or columns. + ValueError: number of pivots cannot exceed the number of rows or columns Matrices must have the number of pivot columns be less than or equal to the number of columns. :: - sage: D=random_matrix(QQ, 1,3, algorithm='echelon_form', num_pivots=5); D + sage: D = random_matrix(QQ, 1,3, algorithm='echelon_form', num_pivots=5); D Traceback (most recent call last): ... - ValueError: number of pivots cannot exceed the number of rows or columns. + ValueError: number of pivots cannot exceed the number of rows or columns Matrices must have the number of pivot columns be greater than zero. :: sage: random_matrix(QQ, 5, 4, algorithm='echelon_form', num_pivots=-1) Traceback (most recent call last): ... - ValueError: the number of pivots must be zero or greater. + ValueError: the number of pivots must be zero or greater AUTHOR: Billy Wonderly (2010-07) """ import sage.probability.probability_distribution as pd - from sage.misc.prandom import randint try: num_pivots = ZZ(num_pivots) except TypeError: - raise TypeError("the number of pivots must be an integer.") + raise TypeError("the number of pivots must be an integer") if num_pivots < 0: - raise ValueError("the number of pivots must be zero or greater.") + raise ValueError("the number of pivots must be zero or greater") ring = parent.base_ring() if not ring.is_exact(): - raise TypeError("the base ring must be exact.") + raise TypeError("the base ring must be exact") num_row = parent.nrows() num_col = parent.ncols() if num_pivots > num_row or num_pivots > num_col: - raise ValueError("number of pivots cannot exceed the number of rows or columns.") + raise ValueError("number of pivots cannot exceed the number of rows or columns") + + if num_pivots == 0: + return parent.zero() + + one = ring.one() + # Create a matrix of the desired size to be modified and then returned. + return_matrix = copy(parent.zero_matrix()) + + # No harm if no pivots at all. + subset = list(range(1, num_col)) + shuffle(subset) + pivots = [0] + sorted(subset[:num_pivots - 1]) + + # Use the list of pivot columns to set the pivot entries of the return_matrix to leading ones. + for pivot_row, pivot in enumerate(pivots): + return_matrix[pivot_row, pivot] = one + if ring is QQ or ring is ZZ: + # Keep track of the non-pivot columns by using the pivot_index, start at the first column to + # the right of the initial pivot column, go until the first column to the left of the next + # pivot column. + for pivot_index in range(num_pivots-1): + for non_pivot_column_index in range(pivots[pivot_index]+1, pivots[pivot_index+1]): + entry_generator1 = pd.RealDistribution("beta", [6, 4]) + # Experimental distribution used to generate the values. + for non_pivot_column_entry in range(pivot_index+1): + sign1 = (2*randint(0,1)-1) + return_matrix[non_pivot_column_entry,non_pivot_column_index]=sign1*int(entry_generator1.get_random_element()*((1-non_pivot_column_entry/return_matrix.ncols())*7)) + # Use index to fill entries of the columns to the right of the last pivot column. + for rest_non_pivot_column in range(pivots[num_pivots-1]+1,num_col): + entry_generator2=pd.RealDistribution("beta",[2.6,4]) + # experimental distribution to generate small values. + for rest_entries in range(num_pivots): + sign2=(2*randint(0,1)-1) + return_matrix[rest_entries,rest_non_pivot_column]=sign2*int(entry_generator2.get_random_element()*5) else: - one = ring.one() - # Create a matrix of the desired size to be modified and then returned. - return_matrix = copy(parent.zero_matrix()) - pivots = [0] #Force first column to be a pivot. No harm if no pivots at all. - # Probability distribution for the placement of leading one's. - pivot_generator = pd.RealDistribution("beta", [1.6, 4.3]) - while len(pivots) < num_pivots: - pivot_column = int(pivot_generator.get_random_element() * num_col) - if pivot_column not in pivots: - pivots.append(pivot_column) - pivots.sort() - pivot_row = 0 - # Use the list of pivot columns to set the pivot entries of the return_matrix to leading ones. - while pivot_row < num_pivots: - return_matrix[pivot_row, pivots[pivot_row]] = one - pivot_row += 1 - if ring is QQ or ring is ZZ: - # Keep track of the non-pivot columns by using the pivot_index, start at the first column to - # the right of the initial pivot column, go until the first column to the left of the next - # pivot column. - for pivot_index in range(num_pivots-1): - for non_pivot_column_index in range(pivots[pivot_index]+1, pivots[pivot_index+1]): - entry_generator1 = pd.RealDistribution("beta", [6, 4]) - # Experimental distribution used to generate the values. - for non_pivot_column_entry in range(pivot_index+1): - sign1 = (2*randint(0,1)-1) - return_matrix[non_pivot_column_entry,non_pivot_column_index]=sign1*int(entry_generator1.get_random_element()*((1-non_pivot_column_entry/return_matrix.ncols())*7)) - # Use index to fill entries of the columns to the right of the last pivot column. - for rest_non_pivot_column in range(pivots[num_pivots-1]+1,num_col): - entry_generator2=pd.RealDistribution("beta",[2.6,4]) - # experimental distribution to generate small values. - for rest_entries in range(num_pivots): - sign2=(2*randint(0,1)-1) - return_matrix[rest_entries,rest_non_pivot_column]=sign2*int(entry_generator2.get_random_element()*5) - else: - for pivot_index in range(num_pivots-1): - for non_pivot_column_index in range(pivots[pivot_index]+1,pivots[pivot_index+1]): - for non_pivot_column_entry in range(pivot_index+1): - return_matrix[non_pivot_column_entry,non_pivot_column_index]=ring.random_element() - for rest_non_pivot_column in range(pivots[num_pivots-1]+1,num_col): - for rest_entries in range(num_pivots): - return_matrix[rest_entries,rest_non_pivot_column]=ring.random_element() + for pivot_index in range(num_pivots-1): + for non_pivot_column_index in range(pivots[pivot_index]+1,pivots[pivot_index+1]): + for non_pivot_column_entry in range(pivot_index+1): + return_matrix[non_pivot_column_entry,non_pivot_column_index]=ring.random_element() + for rest_non_pivot_column in range(pivots[num_pivots-1]+1,num_col): + for rest_entries in range(num_pivots): + return_matrix[rest_entries,rest_non_pivot_column]=ring.random_element() return return_matrix @@ -2692,7 +2695,7 @@ def random_echelonizable_matrix(parent, rank, upper_bound=None, max_tries=100): sage: random_matrix(RR, 3, 3, algorithm='echelonizable', rank=2) Traceback (most recent call last): ... - TypeError: the base ring must be exact. + TypeError: the base ring must be exact Works for rank==1, too. :: From 841fcb77161b32e21b0155524dd594c8a3ab0d87 Mon Sep 17 00:00:00 2001 From: Ricardo Buring Date: Wed, 4 Oct 2023 16:04:42 +0200 Subject: [PATCH 036/216] Fix element labeling in OperationTable.color_table The labels were transposed. --- src/sage/matrix/operation_table.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/sage/matrix/operation_table.py b/src/sage/matrix/operation_table.py index 69cc34d221e..4b3f1dc905c 100644 --- a/src/sage/matrix/operation_table.py +++ b/src/sage/matrix/operation_table.py @@ -1011,9 +1011,8 @@ def color_table(self, element_names=True, cmap=None, **options): # iterate through each element for g in range(n): for h in range(n): - # add text to the plot - tPos = (g, h) + tPos = (h, g) tText = widenames[self._table[g][h]] t = text(tText, tPos, rgbcolor=(0, 0, 0)) plot = plot + t From 6bf409155d734655e6962c47c05bf8273c384421 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Wed, 4 Oct 2023 16:25:26 +0200 Subject: [PATCH 037/216] two minor details in groups --- src/sage/groups/abelian_gps/dual_abelian_group.py | 6 ++++-- src/sage/groups/artin.py | 1 + 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/sage/groups/abelian_gps/dual_abelian_group.py b/src/sage/groups/abelian_gps/dual_abelian_group.py index 2ee86f7f423..85318aa6f83 100644 --- a/src/sage/groups/abelian_gps/dual_abelian_group.py +++ b/src/sage/groups/abelian_gps/dual_abelian_group.py @@ -37,6 +37,8 @@ sage: # needs sage.rings.real_mpfr sage: Fd = F.dual_group(names='ABCDE', base_ring=CC) + sage: Fd.category() + Category of commutative groups sage: A,B,C,D,E = Fd.gens() sage: A(a) # abs tol 1e-8 -1.00000000000000 + 0.00000000000000*I @@ -64,7 +66,7 @@ # Distributed under the terms of the GNU General Public License (GPL) # http://www.gnu.org/licenses/ ########################################################################### - +from sage.categories.groups import Groups from sage.structure.category_object import normalize_names from sage.structure.unique_representation import UniqueRepresentation from sage.groups.abelian_gps.dual_abelian_group_element import ( @@ -129,7 +131,7 @@ def __init__(self, G, names, base_ring): self._group = G names = normalize_names(G.ngens(), names) self._assign_names(names) - AbelianGroupBase.__init__(self) # TODO: category=CommutativeGroups() + AbelianGroupBase.__init__(self, category=Groups().Commutative()) def group(self): """ diff --git a/src/sage/groups/artin.py b/src/sage/groups/artin.py index 4387e503ba7..959744eea57 100644 --- a/src/sage/groups/artin.py +++ b/src/sage/groups/artin.py @@ -142,6 +142,7 @@ def coxeter_group_element(self, W=None): From an element of the Coxeter group it is possible to recover the image by the standard section to the Artin group:: + sage: # needs sage.rings.number_field sage: B(b1) s1*s2*s3*s2 sage: A(c0) From bc15e9ceca82ad55e7825d0a98638d046fb6be95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Wed, 4 Oct 2023 16:51:43 +0200 Subject: [PATCH 038/216] fixing category of ncsym and dual --- src/sage/combinat/ncsym/dual.py | 18 +++++++++++------- src/sage/combinat/ncsym/ncsym.py | 10 +++++++--- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/src/sage/combinat/ncsym/dual.py b/src/sage/combinat/ncsym/dual.py index 5acd9c8f176..961444d5458 100644 --- a/src/sage/combinat/ncsym/dual.py +++ b/src/sage/combinat/ncsym/dual.py @@ -5,12 +5,12 @@ - Travis Scrimshaw (08-04-2013): Initial version """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2013 Travis Scrimshaw # # Distributed under the terms of the GNU General Public License (GPL) -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** from sage.misc.lazy_attribute import lazy_attribute from sage.misc.misc_c import prod @@ -50,7 +50,7 @@ def __init__(self, R): # change the line below to assert(R in Rings()) once MRO issues from #15536, #15475 are resolved assert(R in Fields() or R in Rings()) # side effect of this statement assures MRO exists for R self._base = R # Won't be needed once CategoryObject won't override base_ring - category = GradedHopfAlgebras(R) # TODO: .Commutative() + category = GradedHopfAlgebras(R).Commutative() Parent.__init__(self, category=category.WithRealizations()) # Bases @@ -103,7 +103,7 @@ def dual(self): class w(NCSymBasis_abstract): r""" - The Hopf algebra of symmetric functions in non-commuting variables + The dual Hopf algebra of symmetric functions in non-commuting variables in the `\mathbf{w}` basis. EXAMPLES:: @@ -134,10 +134,14 @@ def __init__(self, NCSymD): """ def key_func_set_part(A): return sorted(map(sorted, A)) - CombinatorialFreeModule.__init__(self, NCSymD.base_ring(), SetPartitions(), + + R = NCSymD.base_ring() + category = GradedHopfAlgebras(R).Commutative() + category &= NCSymDualBases(NCSymD) + CombinatorialFreeModule.__init__(self, R, SetPartitions(), prefix='w', bracket=False, sorting_key=key_func_set_part, - category=NCSymDualBases(NCSymD)) + category=category) @lazy_attribute def to_symmetric_function(self): diff --git a/src/sage/combinat/ncsym/ncsym.py b/src/sage/combinat/ncsym/ncsym.py index 64772ade2d7..d9a5ba37151 100644 --- a/src/sage/combinat/ncsym/ncsym.py +++ b/src/sage/combinat/ncsym/ncsym.py @@ -296,7 +296,7 @@ def __init__(self, R): # change the line below to assert(R in Rings()) once MRO issues from #15536, #15475 are resolved assert(R in Fields() or R in Rings()) # side effect of this statement assures MRO exists for R self._base = R # Won't be needed once CategoryObject won't override base_ring - category = GradedHopfAlgebras(R) # TODO: .Cocommutative() + category = GradedHopfAlgebras(R).Cocommutative() Parent.__init__(self, category=category.WithRealizations()) def _repr_(self): @@ -361,9 +361,13 @@ def __init__(self, NCSym): sage: NCSym = SymmetricFunctionsNonCommutingVariables(QQ) sage: TestSuite(NCSym.m()).run() """ - CombinatorialFreeModule.__init__(self, NCSym.base_ring(), SetPartitions(), + R = NCSym.base_ring() + category = GradedHopfAlgebras(R).Cocommutative() + category &= NCSymBases(NCSym) + + CombinatorialFreeModule.__init__(self, R, SetPartitions(), prefix='m', bracket=False, - category=NCSymBases(NCSym)) + category=category) @cached_method def _m_to_p_on_basis(self, A): From 8361771801e3c37c0546a5c948f9e8b5dd1582c0 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 4 Oct 2023 10:01:02 -0700 Subject: [PATCH 039/216] build/pkgs/setuptools_scm: Update to 8.0.4, change to wheel package --- build/pkgs/setuptools_scm/checksums.ini | 10 +++++----- build/pkgs/setuptools_scm/dependencies | 2 +- build/pkgs/setuptools_scm/package-version.txt | 2 +- build/pkgs/setuptools_scm/spkg-install.in | 1 - 4 files changed, 7 insertions(+), 8 deletions(-) delete mode 100644 build/pkgs/setuptools_scm/spkg-install.in diff --git a/build/pkgs/setuptools_scm/checksums.ini b/build/pkgs/setuptools_scm/checksums.ini index d4c9ee1a391..fd10a17aea2 100644 --- a/build/pkgs/setuptools_scm/checksums.ini +++ b/build/pkgs/setuptools_scm/checksums.ini @@ -1,5 +1,5 @@ -tarball=setuptools_scm-VERSION.tar.gz -sha1=b8c9447fe6dfc44107c9cbd2fd82314aad3cb95e -md5=0df4e7fd923e4983cd65786efaa0e0d0 -cksum=3196930290 -upstream_url=https://pypi.io/packages/source/s/setuptools_scm/setuptools_scm-VERSION.tar.gz +tarball=setuptools_scm-VERSION-py3-none-any.whl +sha1=cfde7254fe351b69cd4bf02e1b57e0b3c59aa9a6 +md5=4c054a609965886703ede26a4ba3206d +cksum=1360813947 +upstream_url=https://pypi.io/packages/py3/s/setuptools_scm/setuptools_scm-VERSION-py3-none-any.whl diff --git a/build/pkgs/setuptools_scm/dependencies b/build/pkgs/setuptools_scm/dependencies index 7dd3b6e8f6e..e8117f8900b 100644 --- a/build/pkgs/setuptools_scm/dependencies +++ b/build/pkgs/setuptools_scm/dependencies @@ -1,4 +1,4 @@ - typing_extensions | setuptools pip wheel tomli packaging $(PYTHON) +packaging setuptools tomli typing_extensions | pip $(PYTHON) ---------- All lines of this file are ignored except the first. diff --git a/build/pkgs/setuptools_scm/package-version.txt b/build/pkgs/setuptools_scm/package-version.txt index 2be8aeb6b14..50c496d20c6 100644 --- a/build/pkgs/setuptools_scm/package-version.txt +++ b/build/pkgs/setuptools_scm/package-version.txt @@ -1 +1 @@ -7.0.5 +8.0.4 diff --git a/build/pkgs/setuptools_scm/spkg-install.in b/build/pkgs/setuptools_scm/spkg-install.in deleted file mode 100644 index deba1bb42bb..00000000000 --- a/build/pkgs/setuptools_scm/spkg-install.in +++ /dev/null @@ -1 +0,0 @@ -cd src && sdh_pip_install . From 0461f9063ab6227df9de850821892ff91be3aca7 Mon Sep 17 00:00:00 2001 From: "Alex J. Best" Date: Wed, 4 Oct 2023 21:11:36 +0200 Subject: [PATCH 040/216] lift --- src/sage/rings/polynomial/multi_polynomial_libsingular.pyx | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx b/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx index 45e14eb320d..d04e29736d9 100644 --- a/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx +++ b/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx @@ -4499,8 +4499,6 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): """ global errorreported - if not self._parent._base.is_field(): - raise NotImplementedError("Lifting of multivariate polynomials over non-fields is not implemented.") cdef ideal *fI = idInit(1,1) cdef ideal *_I From 686cdd90c857457a43564f4f9cf726548aaa3d84 Mon Sep 17 00:00:00 2001 From: "John H. Palmieri" Date: Tue, 3 Oct 2023 21:54:10 -0700 Subject: [PATCH 041/216] Deprecate the backslash operator --- src/doc/de/tutorial/tour_linalg.rst | 10 ------ src/doc/en/tutorial/tour_linalg.rst | 10 ------ src/doc/es/tutorial/tour_linalg.rst | 10 ------ src/doc/fr/tutorial/tour_linalg.rst | 11 ------ src/doc/ja/tutorial/tour_linalg.rst | 12 ------- src/doc/pt/tutorial/tour_linalg.rst | 10 ------ src/doc/ru/tutorial/tour_linalg.rst | 9 ----- src/sage/combinat/binary_tree.py | 5 +-- src/sage/features/sagemath.py | 2 +- src/sage/matrix/matrix2.pyx | 35 +++++++++++-------- src/sage/matrix/matrix_complex_ball_dense.pyx | 6 ++-- src/sage/matrix/matrix_integer_dense.pyx | 12 +++---- src/sage/matrix/matrix_integer_sparse.pyx | 6 ++-- .../matrix/matrix_modn_dense_template.pxi | 2 +- src/sage/matrix/matrix_modn_sparse.pyx | 6 ++-- src/sage/matrix/matrix_space.py | 4 +-- src/sage/matroids/basis_exchange_matroid.pyx | 4 +-- src/sage/matroids/catalog.py | 2 +- src/sage/matroids/linear_matroid.pyx | 22 ++++++------ src/sage/matroids/matroid.pyx | 33 ++++++++++------- src/sage/matroids/minor_matroid.py | 8 ++--- src/sage/misc/misc.py | 19 ++++++++++ .../linalg_doctest.py | 2 ++ .../linsolve_doctest.py | 2 +- 24 files changed, 103 insertions(+), 139 deletions(-) diff --git a/src/doc/de/tutorial/tour_linalg.rst b/src/doc/de/tutorial/tour_linalg.rst index 2a5467e8884..1be6540c89e 100644 --- a/src/doc/de/tutorial/tour_linalg.rst +++ b/src/doc/de/tutorial/tour_linalg.rst @@ -42,16 +42,6 @@ gelöst werden. Das Auswerten von ``A.solve_right(Y)`` gibt eine Matrix sage: A * X # wir überprüfen unsere Antwort... (0, -4, -1) -Anstelle von ``solve_right`` kann auch ein Backslash ``\`` verwendet -werden. Benutzen Sie ``A \ Y`` anstelle von ``A.solve_right(Y)``. - -.. link - -:: - - sage: A \ Y - (-2, 1, 0) - Falls keine Lösung existiert, gibt Sage einen Fehler zurück: .. skip diff --git a/src/doc/en/tutorial/tour_linalg.rst b/src/doc/en/tutorial/tour_linalg.rst index 054e338cea7..84a45f4931b 100644 --- a/src/doc/en/tutorial/tour_linalg.rst +++ b/src/doc/en/tutorial/tour_linalg.rst @@ -42,16 +42,6 @@ Evaluating ``A.solve_right(Y)`` returns a matrix (or vector) sage: A * X # checking our answer... (0, -4, -1) -A backslash ``\`` can be used in the place of ``solve_right``; use -``A \ Y`` instead of ``A.solve_right(Y)``. - -.. link - -:: - - sage: A \ Y - (-2, 1, 0) - If there is no solution, Sage returns an error: .. skip diff --git a/src/doc/es/tutorial/tour_linalg.rst b/src/doc/es/tutorial/tour_linalg.rst index eb2caa35440..a9b543cca0e 100644 --- a/src/doc/es/tutorial/tour_linalg.rst +++ b/src/doc/es/tutorial/tour_linalg.rst @@ -49,16 +49,6 @@ Resolver ecuaciones matriciales es sencillo, usando el método sage: A * X # comprobando la solución... (0, -4, -1) -Se puede usar una barra invertida ``\`` en lugar de ``solve_right``; -usamos ``A \ Y`` en lugar de ``A.solve_right(Y)``. - -.. link - -:: - - sage: A \ Y - (-2, 1, 0) - Si no hay solución, Sage lanza un error: .. skip diff --git a/src/doc/fr/tutorial/tour_linalg.rst b/src/doc/fr/tutorial/tour_linalg.rst index 1343fa126fa..582a915edef 100644 --- a/src/doc/fr/tutorial/tour_linalg.rst +++ b/src/doc/fr/tutorial/tour_linalg.rst @@ -42,17 +42,6 @@ une matrice (ou un vecteur) :math:`X` tel que :math:`AX=Y`: sage: A * X # vérifions la réponse... (0, -4, -1) -Un antislash (contre-oblique) ``\`` peut être employé à la place de -``solve_right`` : il suffit d'écrire ``A \ Y`` au lieu de -``A.solve_right(Y)``. - -.. link - -:: - - sage: A \ Y - (-2, 1, 0) - S'il n'y a aucune solution, Sage renvoie une erreur : .. skip diff --git a/src/doc/ja/tutorial/tour_linalg.rst b/src/doc/ja/tutorial/tour_linalg.rst index cf24ab37ed1..7af81486a30 100644 --- a/src/doc/ja/tutorial/tour_linalg.rst +++ b/src/doc/ja/tutorial/tour_linalg.rst @@ -45,18 +45,6 @@ Sageでは,行列 :math:`A` の核空間は「左」核空間,すなわち : (0, -4, -1) -``solve_right`` の代わりにバックスラッシュ ``\`` を使うこともできる. -つまり ``A.solve_right(Y)`` ではなく ``A \ Y`` と書くわけである. - -.. link - -:: - - sage: A \ Y - (-2, 1, 0) - - - 解がない場合は,Sageはエラーを返してくる: .. skip diff --git a/src/doc/pt/tutorial/tour_linalg.rst b/src/doc/pt/tutorial/tour_linalg.rst index 9cdf7671dd7..806a36c6446 100644 --- a/src/doc/pt/tutorial/tour_linalg.rst +++ b/src/doc/pt/tutorial/tour_linalg.rst @@ -40,16 +40,6 @@ Calculando ``A.solve_right(Y)`` obtém-se uma matrix (ou vetor) sage: A * X # checking our answer... (0, -4, -1) -Uma barra invertida ``\`` pode ser usada no lugar de ``solve_right``; -use ``A \ Y`` no lugar de ``A.solve_right(Y)``. - -.. link - -:: - - sage: A \ Y - (-2, 1, 0) - Se não existir solução, o Sage retorna um erro: .. skip diff --git a/src/doc/ru/tutorial/tour_linalg.rst b/src/doc/ru/tutorial/tour_linalg.rst index 2e1e6620549..6b4c64764c8 100644 --- a/src/doc/ru/tutorial/tour_linalg.rst +++ b/src/doc/ru/tutorial/tour_linalg.rst @@ -37,15 +37,6 @@ Sage поддерживает стандартные конструкции из sage: A * X # проверка... (0, -4, -1) -``\`` может быть использован вместо ``solve_right``; используйте -``A \ Y`` вместо ``A.solve_right(Y)``. - -.. link - -:: - - sage: A \ Y - (-2, 1, 0) Если решения не существует, то Sage вернет ошибку: diff --git a/src/sage/combinat/binary_tree.py b/src/sage/combinat/binary_tree.py index 8e876ab137a..f086f893601 100644 --- a/src/sage/combinat/binary_tree.py +++ b/src/sage/combinat/binary_tree.py @@ -39,6 +39,7 @@ from sage.sets.disjoint_union_enumerated_sets import DisjointUnionEnumeratedSets from sage.sets.family import Family from sage.misc.cachefunc import cached_method +from sage.misc.superseded import deprecated_function_alias class BinaryTree(AbstractClonableTree, ClonableArray, @@ -3214,7 +3215,7 @@ def under(self, bt): sage: b1 = BinaryTree([[],[]]) sage: b2 = BinaryTree([None,[]]) - sage: ascii_art((b1, b2, b1 \ b2)) + sage: ascii_art((b1, b2, b1.under(b2))) ( o , o , _o_ ) ( / \ \ / \ ) ( o o o o o ) @@ -3276,7 +3277,7 @@ def under(self, bt): else: return B([self.under(bt[0]), bt[1]]) - _backslash_ = under + _backslash_ = deprecated_function_alias(36394, under) def under_decomposition(self): r""" diff --git a/src/sage/features/sagemath.py b/src/sage/features/sagemath.py index ac3922552e4..7404e6d0a8e 100644 --- a/src/sage/features/sagemath.py +++ b/src/sage/features/sagemath.py @@ -232,7 +232,7 @@ class sage__graphs(JoinFeature): sage: M = Matroid(Matrix(QQ, [[1, 0, 0, 0, 1, 1, 1], ....: [0, 1, 0, 1, 0, 1, 1], ....: [0, 0, 1, 1, 1, 0, 1]])) - sage: N = M / [2] \ [3, 4] + sage: N = (M / [2]).delete([3, 4]) sage: sorted(N.groundset()) [0, 1, 5, 6] diff --git a/src/sage/matrix/matrix2.pyx b/src/sage/matrix/matrix2.pyx index 86aca6e00d8..1798f6ba0a7 100644 --- a/src/sage/matrix/matrix2.pyx +++ b/src/sage/matrix/matrix2.pyx @@ -106,7 +106,7 @@ from sage.matrix.matrix_misc import permanental_minor_polynomial from sage.misc.misc_c import prod # used to deprecate only adjoint method -from sage.misc.superseded import deprecated_function_alias +from sage.misc.superseded import deprecation, deprecated_function_alias # temporary hack to silence the warnings from #34806 @@ -146,21 +146,28 @@ cdef class Matrix(Matrix1): Used to compute `A \backslash B`, i.e., the backslash solver operator. + DEPRECATED + EXAMPLES:: sage: A = matrix(QQ, 3, [1,2,4,2,3,1,0,1,2]) sage: B = matrix(QQ, 3, 2, [1,7,5, 2,1,3]) sage: C = A._backslash_(B); C + doctest:...: DeprecationWarning: the backslash operator has been deprecated; use A.solve_right(B) instead + See https://github.com/sagemath/sage/issues/36394 for details. [ -1 1] [13/5 -3/5] [-4/5 9/5] sage: A*C == B True sage: A._backslash_(B) == A \ B + doctest:...: DeprecationWarning: the backslash operator has been deprecated; use A.solve_right(B) instead + See https://github.com/sagemath/sage/issues/36394 for details. True sage: A._backslash_(B) == A.solve_right(B) True """ + deprecation(36394, 'the backslash operator has been deprecated; use A.solve_right(B) instead') return self.solve_right(B) def subs(self, *args, **kwds): @@ -462,7 +469,7 @@ cdef class Matrix(Matrix1): .. NOTE:: - In Sage one can also write ``A \ B`` for + DEPRECATED. In Sage one can also write ``A \ B`` for ``A.solve_right(B)``, that is, Sage implements "the MATLAB/Octave backslash operator". @@ -506,7 +513,7 @@ cdef class Matrix(Matrix1): sage: A = matrix(QQ, 3, [1,2,3,-1,2,5,2,3,1]) sage: b = vector(QQ,[1,2,3]) - sage: x = A \ b; x + sage: x = A.solve_right(b); x (-13/12, 23/12, -7/12) sage: A * x (1, 2, 3) @@ -525,7 +532,7 @@ cdef class Matrix(Matrix1): Another nonsingular example:: sage: A = matrix(QQ,2,3, [1,2,3,2,4,6]); v = vector([-1/2,-1]) - sage: x = A \ v; x + sage: x = A.solve_right(v); x (-1/2, 0, 0) sage: A*x == v True @@ -533,13 +540,13 @@ cdef class Matrix(Matrix1): Same example but over `\ZZ`:: sage: A = matrix(ZZ,2,3, [1,2,3,2,4,6]); v = vector([-1,-2]) - sage: A \ v + sage: A.solve_right(v) (-1, 0, 0) An example in which there is no solution:: sage: A = matrix(QQ,2,3, [1,2,3,2,4,6]); v = vector([1,1]) - sage: A \ v + sage: A.solve_right(v) Traceback (most recent call last): ... ValueError: matrix equation has no solutions @@ -564,24 +571,24 @@ cdef class Matrix(Matrix1): sage: A*X == B True - We illustrate left associativity, etc., of the backslash operator. + We illustrate left associativity, etc., of the ``solve_right`` operator. :: sage: A = matrix(QQ, 2, [1,2,3,4]) - sage: A \ A + sage: A.solve_right(A) [1 0] [0 1] - sage: A \ A \ A + sage: (A.solve_right(A)).solve_right(A) [1 2] [3 4] - sage: A.parent()(1) \ A + sage: A.parent()(1).solve_right(A) [1 2] [3 4] - sage: A \ (A \ A) + sage: A.solve_right(A.solve_right(A)) [ -2 1] [ 3/2 -1/2] - sage: X = A \ (A - 2); X + sage: X = A.solve_right(A - 2); X [ 5 -2] [-3 2] sage: A * X @@ -593,7 +600,7 @@ cdef class Matrix(Matrix1): sage: x = polygen(QQ, 'x') sage: A = matrix(2, [x,2*x,-5*x^2+1,3]) sage: v = vector([3,4*x - 2]) - sage: X = A \ v + sage: X = A.solve_right(v) sage: X ((-4/5*x^2 + 2/5*x + 9/10)/(x^3 + 1/10*x), (19/10*x^2 - 1/5*x - 3/10)/(x^3 + 1/10*x)) sage: A * X == v @@ -635,7 +642,7 @@ cdef class Matrix(Matrix1): [ 2 + O(5^4) 5 + O(5^5) 4 + O(5^4)] [ 1 + O(5^4) 1 + O(5^4) 2 + O(5^4)] sage: v = vector(k, 3, [1,2,3]) - sage: x = a \ v; x + sage: x = a.solve_right(v); x (4 + 5 + 5^2 + 3*5^3 + O(5^4), 2 + 5 + 3*5^2 + 5^3 + O(5^4), 1 + 5 + O(5^4)) sage: a * x == v True diff --git a/src/sage/matrix/matrix_complex_ball_dense.pyx b/src/sage/matrix/matrix_complex_ball_dense.pyx index 47ca41070fa..3f56772a663 100644 --- a/src/sage/matrix/matrix_complex_ball_dense.pyx +++ b/src/sage/matrix/matrix_complex_ball_dense.pyx @@ -569,14 +569,14 @@ cdef class Matrix_complex_ball_dense(Matrix_dense): r""" TESTS:: - sage: matrix(CBF, [[1/2, 1/3], [1, 1]]) \ vector([-1, 1]) + sage: matrix(CBF, [[1/2, 1/3], [1, 1]]).solve_right(vector([-1, 1])) ([-8.00000000000000 +/- ...], [9.00000000000000 +/- ...]) - sage: matrix(CBF, 2, 2, 0) \ vector([-1, 1]) + sage: matrix(CBF, 2, 2, 0).solve_right(vector([-1, 1])) Traceback (most recent call last): ... ValueError: unable to invert this matrix sage: b = CBF(0, RBF(0, rad=.1r)) - sage: matrix(CBF, [[1, 1], [0, b]]) \ vector([-1, 1]) + sage: matrix(CBF, [[1, 1], [0, b]]).solve_right(vector([-1, 1])) Traceback (most recent call last): ... ValueError: unable to invert this matrix diff --git a/src/sage/matrix/matrix_integer_dense.pyx b/src/sage/matrix/matrix_integer_dense.pyx index 8c276f2ca29..b093e576f74 100644 --- a/src/sage/matrix/matrix_integer_dense.pyx +++ b/src/sage/matrix/matrix_integer_dense.pyx @@ -4138,7 +4138,7 @@ cdef class Matrix_integer_dense(Matrix_dense): .. NOTE:: - In Sage one can also write ``A \ B`` for + DEPRECATED. In Sage one can also write ``A \ B`` for ``A.solve_right(B)``, i.e., Sage implements the "the MATLAB/Octave backslash operator". @@ -4162,7 +4162,7 @@ cdef class Matrix_integer_dense(Matrix_dense): sage: a = matrix(ZZ, 2, [0, -1, 1, 0]) sage: v = vector(ZZ, [2, 3]) - sage: a \ v + sage: a.solve_right(v) (3, -2) Note that the output vector or matrix is always over @@ -4170,7 +4170,7 @@ cdef class Matrix_integer_dense(Matrix_dense): :: - sage: parent(a\v) + sage: parent(a.solve_right(v)) Vector space of dimension 2 over Rational Field We solve a bigger system where the answer is over the rationals. @@ -4179,7 +4179,7 @@ cdef class Matrix_integer_dense(Matrix_dense): sage: a = matrix(ZZ, 3, 3, [1,2,3,4, 5, 6, 8, -2, 3]) sage: v = vector(ZZ, [1,2,3]) - sage: w = a \ v; w + sage: w = a.solve_right(v); w (2/15, -4/15, 7/15) sage: parent(w) Vector space of dimension 3 over Rational Field @@ -4193,7 +4193,7 @@ cdef class Matrix_integer_dense(Matrix_dense): sage: a = matrix(ZZ, 3, 3, [1,2,3,4, 5, 6, 8, -2, 3]) sage: b = matrix(ZZ, 3, 2, [1,5, 2, -3, 3, 0]) - sage: w = a \ b; w + sage: w = a.solve_right(b); w [ 2/15 -19/5] [-4/15 -27/5] [ 7/15 98/15] @@ -4214,7 +4214,7 @@ cdef class Matrix_integer_dense(Matrix_dense): sage: n = 100 sage: a = random_matrix(ZZ,n) sage: v = vector(ZZ,n,range(n)) - sage: x = a \ v + sage: x = a.solve_right(v) sage: a * x == v True diff --git a/src/sage/matrix/matrix_integer_sparse.pyx b/src/sage/matrix/matrix_integer_sparse.pyx index f6d79abf56a..f4320fcd914 100644 --- a/src/sage/matrix/matrix_integer_sparse.pyx +++ b/src/sage/matrix/matrix_integer_sparse.pyx @@ -985,7 +985,7 @@ cdef class Matrix_integer_sparse(Matrix_sparse): .. NOTE:: - In Sage one can also write ``A \ B`` for + DEPRECATED. In Sage one can also write ``A \ B`` for ``A.solve_right(B)``, i.e., Sage implements the "the MATLAB/Octave backslash operator". @@ -1019,14 +1019,14 @@ cdef class Matrix_integer_sparse(Matrix_sparse): sage: A = matrix(ZZ, 3, [1,2,3,-1,2,5,2,3,1], sparse=True) sage: b = vector(ZZ, [1,2,3]) - sage: x = A \ b + sage: x = A.solve_right(b) sage: x (-13/12, 23/12, -7/12) sage: A * x (1, 2, 3) sage: u = matrix(ZZ, 3, 2, [0,1,1,1,0,2]) - sage: x = A \ u + sage: x = A.solve_right(u) sage: x [-7/12 -1/6] [ 5/12 5/6] diff --git a/src/sage/matrix/matrix_modn_dense_template.pxi b/src/sage/matrix/matrix_modn_dense_template.pxi index 69569297923..f00e8bef6ef 100644 --- a/src/sage/matrix/matrix_modn_dense_template.pxi +++ b/src/sage/matrix/matrix_modn_dense_template.pxi @@ -23,7 +23,7 @@ EXAMPLES:: sage: A.rank() 4 sage: v = vector(GF(127), 4, (100, 93, 47, 110)) - sage: x = A\v + sage: x = A.solve_right(v) sage: A*x == v True diff --git a/src/sage/matrix/matrix_modn_sparse.pyx b/src/sage/matrix/matrix_modn_sparse.pyx index 80a74bf1761..9c12d6b9e1d 100644 --- a/src/sage/matrix/matrix_modn_sparse.pyx +++ b/src/sage/matrix/matrix_modn_sparse.pyx @@ -880,7 +880,7 @@ cdef class Matrix_modn_sparse(Matrix_sparse): .. NOTE:: - In Sage one can also write ``A \ B`` for + DEPRECATED. In Sage one can also write ``A \ B`` for ``A.solve_right(B)``, i.e., Sage implements the "the MATLAB/Octave backslash operator". @@ -914,14 +914,14 @@ cdef class Matrix_modn_sparse(Matrix_sparse): sage: A = matrix(ZZ, 3, [1,2,3,-1,2,5,2,3,1], sparse=True) sage: b = vector(ZZ, [1,2,3]) - sage: x = A \ b + sage: x = A.solve_right(b) sage: x (-13/12, 23/12, -7/12) sage: A * x (1, 2, 3) sage: u = matrix(ZZ, 3, 2, [0,1,1,1,0,2]) - sage: x = A \ u + sage: x = A.solve_right(u) sage: x [-7/12 -1/6] [ 5/12 5/6] diff --git a/src/sage/matrix/matrix_space.py b/src/sage/matrix/matrix_space.py index 6aab58352be..ca77503ba96 100644 --- a/src/sage/matrix/matrix_space.py +++ b/src/sage/matrix/matrix_space.py @@ -677,9 +677,9 @@ def __init__(self, base_ring, nrows, ncols, sparse, implementation): Vector space of degree 125 and dimension 124 over Rational Field Basis matrix: 124 x 125 dense matrix over Rational Field - sage: MatrixSpace(ZZ,20,20)(1) \ MatrixSpace(ZZ,20,1).random_element() + sage: MatrixSpace(ZZ,20,20)(1).solve_right(MatrixSpace(ZZ,20,1).random_element()) 20 x 1 dense matrix over Rational Field (use the '.str()' method to see the entries) - sage: MatrixSpace(ZZ,200,200)(1) \ MatrixSpace(ZZ,200,1).random_element() + sage: MatrixSpace(ZZ,200,200)(1).solve_right(MatrixSpace(ZZ,200,1).random_element()) 200 x 1 dense matrix over Rational Field (use the '.str()' method to see the entries) sage: A = MatrixSpace(RDF,1000,1000).random_element() sage: B = MatrixSpace(RDF,1000,1000).random_element() diff --git a/src/sage/matroids/basis_exchange_matroid.pyx b/src/sage/matroids/basis_exchange_matroid.pyx index 015fa8b8df3..fc902bc19c0 100644 --- a/src/sage/matroids/basis_exchange_matroid.pyx +++ b/src/sage/matroids/basis_exchange_matroid.pyx @@ -1134,7 +1134,7 @@ cdef class BasisExchangeMatroid(Matroid): sage: M.connectivity(X) 2 sage: J = M.groundset()-(S|T|I) - sage: N = M/I\J + sage: N = (M/I).delete(J) sage: N.connectivity(S) 2 """ @@ -2132,7 +2132,7 @@ cdef class BasisExchangeMatroid(Matroid): sage: N._is_isomorphism(M, {e:e for e in M.groundset()}) False - sage: M = matroids.named_matroids.Fano() \ ['g'] + sage: M = matroids.named_matroids.Fano().delete(['g']) sage: N = matroids.Wheel(3) sage: morphism = {'a':0, 'b':1, 'c': 2, 'd':4, 'e':5, 'f':3} sage: M._is_isomorphism(N, morphism) diff --git a/src/sage/matroids/catalog.py b/src/sage/matroids/catalog.py index 4bc93a6b8a0..949f7367b40 100644 --- a/src/sage/matroids/catalog.py +++ b/src/sage/matroids/catalog.py @@ -1006,7 +1006,7 @@ def AG(n, q, x=None): EXAMPLES:: - sage: M = matroids.AG(2, 3) \ 8 + sage: M = matroids.AG(2, 3).delete(8) sage: M.is_isomorphic(matroids.named_matroids.AG23minus()) True sage: matroids.AG(5, 4, 'z').size() == ((4 ^ 6 - 1) / (4 - 1) - # needs sage.rings.finite_rings diff --git a/src/sage/matroids/linear_matroid.pyx b/src/sage/matroids/linear_matroid.pyx index 36f563aa433..8ba09084c1f 100644 --- a/src/sage/matroids/linear_matroid.pyx +++ b/src/sage/matroids/linear_matroid.pyx @@ -819,7 +819,7 @@ cdef class LinearMatroid(BasisExchangeMatroid): EXAMPLES:: sage: from sage.matroids.advanced import * - sage: M = matroids.named_matroids.Fano() \ ['g'] + sage: M = matroids.named_matroids.Fano().delete(['g']) sage: N = BinaryMatroid(Matrix(matroids.Wheel(3))) sage: morphism = {'a':0, 'b':1, 'c': 2, 'd':4, 'e':5, 'f':3} sage: M._is_field_isomorphism(N, morphism) @@ -1004,7 +1004,7 @@ cdef class LinearMatroid(BasisExchangeMatroid): False sage: from sage.matroids.advanced import * - sage: M = matroids.named_matroids.Fano() \ ['g'] + sage: M = matroids.named_matroids.Fano().delete(['g']) sage: N = LinearMatroid(reduced_matrix=Matrix(GF(2), ....: [[-1, 0, 1], [1, -1, 0], [0, 1, -1]])) sage: morphism = {'a':0, 'b':1, 'c': 2, 'd':4, 'e':5, 'f':3} @@ -3413,8 +3413,8 @@ cdef class BinaryMatroid(LinearMatroid): EXAMPLES:: - sage: M = matroids.named_matroids.Fano() \ ['a'] - sage: N = matroids.named_matroids.Fano() \ ['b'] + sage: M = matroids.named_matroids.Fano().delete(['a']) + sage: N = matroids.named_matroids.Fano().delete(['b']) sage: morphism = {'b':'a', 'c':'c', 'd':'e', 'e':'d', 'f':'f', 'g':'g'} sage: M._is_isomorphism(N, morphism) True @@ -3632,7 +3632,7 @@ cdef class BinaryMatroid(LinearMatroid): 2 sage: for i in [-1, 0, 1]: ....: print(sorted(e for e in M.groundset() - ....: if (M\e).bicycle_dimension() == 2 + i)) + ....: if (M.delete(e)).bicycle_dimension() == 2 + i)) ['a', 'b', 'c', 'e', 'f', 'g'] ['d'] ['h'] @@ -5459,7 +5459,7 @@ cdef class QuaternaryMatroid(LinearMatroid): EXAMPLES:: sage: # needs sage.rings.finite_rings - sage: M = matroids.named_matroids.Q10()\'a' + sage: M = matroids.named_matroids.Q10().delete('a') sage: for F in M._principal_tripartition(): print(sorted(F)) ['b', 'c', 'd', 'e', 'h', 'i'] ['f', 'g', 'j'] @@ -5468,7 +5468,7 @@ cdef class QuaternaryMatroid(LinearMatroid): 1 sage: for i in [-1, 0, 1]: ....: print(sorted(e for e in M.groundset() - ....: if (M\e).bicycle_dimension() == 1 + i)) + ....: if (M.delete(e)).bicycle_dimension() == 1 + i)) ['b', 'c', 'd', 'e', 'h', 'i'] ['f', 'g', 'j'] [] @@ -5497,8 +5497,8 @@ cdef class QuaternaryMatroid(LinearMatroid): EXAMPLES:: - sage: M = matroids.named_matroids.Q10()\'a' # needs sage.rings.finite_rings - sage: N = matroids.named_matroids.Q10()\'b' # needs sage.rings.finite_rings + sage: M = matroids.named_matroids.Q10().delete('a') # needs sage.rings.finite_rings + sage: N = matroids.named_matroids.Q10().delete('b') # needs sage.rings.finite_rings sage: M._fast_isom_test(N) is None # needs sage.rings.finite_rings True """ @@ -6182,8 +6182,8 @@ cdef class RegularMatroid(LinearMatroid): EXAMPLES:: - sage: M = matroids.named_matroids.R10()\'a' - sage: N = matroids.named_matroids.R10()\'b' + sage: M = matroids.named_matroids.R10().delete('a') + sage: N = matroids.named_matroids.R10().delete('b') sage: M._fast_isom_test(N) # needs sage.graphs True """ diff --git a/src/sage/matroids/matroid.pyx b/src/sage/matroids/matroid.pyx index 4d19c589bdf..93976cd6e43 100644 --- a/src/sage/matroids/matroid.pyx +++ b/src/sage/matroids/matroid.pyx @@ -280,7 +280,7 @@ Minors:: sage: M = Matroid(Matrix(QQ, [[1, 0, 0, 0, 1, 1, 1], ....: [0, 1, 0, 1, 0, 1, 1], ....: [0, 0, 1, 1, 1, 0, 1]])) - sage: N = M / [2] \ [3, 4] + sage: N = (M / [2]).delete([3, 4]) sage: sorted(N.groundset()) [0, 1, 5, 6] sage: N.full_rank() @@ -337,6 +337,7 @@ from itertools import combinations, product from sage.matrix.constructor import matrix from sage.misc.lazy_import import LazyImport from sage.misc.prandom import shuffle +from sage.misc.superseded import deprecation from sage.rings.integer_ring import ZZ from sage.structure.richcmp cimport rich_to_bool, richcmp from sage.structure.sage_object cimport SageObject @@ -2142,7 +2143,7 @@ cdef class Matroid(SageObject): sage: M = matroids.named_matroids.Fano().dual() sage: M.coloops() frozenset() - sage: (M \ ['a', 'b']).coloops() + sage: (M.delete(['a', 'b'])).coloops() frozenset({'f'}) """ return self._coclosure(set()) @@ -3475,7 +3476,7 @@ cdef class Matroid(SageObject): sage: N.is_isomorphism(M, {e:e for e in M.groundset()}) False - sage: M = matroids.named_matroids.Fano() \ ['g'] + sage: M = matroids.named_matroids.Fano().delete(['g']) sage: N = matroids.Wheel(3) sage: morphism = {'a':0, 'b':1, 'c': 2, 'd':4, 'e':5, 'f':3} sage: M.is_isomorphism(N, morphism) @@ -3603,7 +3604,7 @@ cdef class Matroid(SageObject): sage: N._is_isomorphism(M, {e:e for e in M.groundset()}) False - sage: M = matroids.named_matroids.Fano() \ ['g'] + sage: M = matroids.named_matroids.Fano().delete(['g']) sage: N = matroids.Wheel(3) sage: morphism = {'a':0, 'b':1, 'c': 2, 'd':4, 'e':5, 'f':3} sage: M._is_isomorphism(N, morphism) @@ -3907,7 +3908,8 @@ cdef class Matroid(SageObject): one. It can be shown that the resulting matroid does not depend on the order of the deletions. - Sage supports the shortcut notation ``M \ X`` for ``M.delete(X)``. + DEPRECATED: Sage supports the shortcut notation ``M \ X`` for + ``M.delete(X)``. INPUT: @@ -3932,7 +3934,7 @@ cdef class Matroid(SageObject): ['a', 'b', 'c', 'd', 'e', 'f', 'g'] sage: M.delete(['a', 'c']) Binary matroid of rank 3 on 5 elements, type (1, 6) - sage: M.delete(['a']) == M \ ['a'] + sage: M.delete(['a']) == M.delete(['a']) True One can use a single element, rather than a set:: @@ -3940,13 +3942,13 @@ cdef class Matroid(SageObject): sage: M = matroids.CompleteGraphic(4) # needs sage.graphs sage: M.delete(1) == M.delete([1]) # needs sage.graphs True - sage: M \ 1 # needs sage.graphs + sage: M.delete(1) # needs sage.graphs Graphic matroid of rank 3 on 5 elements Note that one can iterate over strings:: sage: M = matroids.named_matroids.Fano() - sage: M \ 'abc' + sage: M.delete('abc') Binary matroid of rank 3 on 4 elements, type (0, 5) The following is therefore ambiguous. Sage will delete the single @@ -3954,7 +3956,7 @@ cdef class Matroid(SageObject): sage: M = Matroid(groundset=['a', 'b', 'c', 'abc'], ....: bases=[['a', 'b', 'c'], ['a', 'b', 'abc']]) - sage: sorted((M \ 'abc').groundset()) + sage: sorted((M.delete('abc')).groundset()) ['a', 'b', 'c'] """ return self.minor(deletions=X) @@ -3963,12 +3965,17 @@ cdef class Matroid(SageObject): r""" Shorthand for ``self.delete(X)``. + DEPRECATED + EXAMPLES:: sage: M = matroids.CompleteGraphic(4) # needs sage.graphs sage: M.delete(1) == M \ 1 # indirect doctest # needs sage.graphs + doctest:...: DeprecationWarning: the backslash operator has been deprecated; use M.delete(X) instead + See https://github.com/sagemath/sage/issues/36394 for details. True """ + deprecation(36394, 'the backslash operator has been deprecated; use M.delete(X) instead') return self.delete(X) cpdef dual(self): @@ -4399,7 +4406,7 @@ cdef class Matroid(SageObject): `\{b, f\}`:: sage: M = matroids.named_matroids.S8() - sage: N = M \ 'h' + sage: N = M.delete('h') sage: frozenset('bf') in N.modular_cut(['cg', 'ae']) True @@ -4768,7 +4775,7 @@ cdef class Matroid(SageObject): sage: M = matroids.named_matroids.Fano().dual() sage: M.is_cosimple() True - sage: N = M \ 'a' + sage: N = M.delete('a') sage: N.is_cosimple() False """ @@ -4977,7 +4984,7 @@ cdef class Matroid(SageObject): sage: M.connectivity(X) 2 sage: J = M.groundset()-(S|T|I) - sage: N = M/I\J + sage: N = (M/I).delete(J) sage: N.connectivity(S) 2 """ @@ -5026,7 +5033,7 @@ cdef class Matroid(SageObject): sage: M.connectivity(X) 2 sage: J = M.groundset()-(S|T|I) - sage: N = M/I\J + sage: N = (M/I).delete(J) sage: N.connectivity(S) 2 """ diff --git a/src/sage/matroids/minor_matroid.py b/src/sage/matroids/minor_matroid.py index 98856348ac1..ff27affc665 100644 --- a/src/sage/matroids/minor_matroid.py +++ b/src/sage/matroids/minor_matroid.py @@ -14,11 +14,11 @@ EXAMPLES:: sage: M = matroids.named_matroids.Fano() - sage: M \ ['a', 'c' ] == M.delete(['a', 'c']) + sage: M.delete(['a', 'c' ]) == M.delete(['a', 'c']) True sage: M / 'a' == M.contract('a') True - sage: M / 'c' \ 'ab' == M.minor(contractions='c', deletions='ab') + sage: (M / 'c').delete('ab') == M.minor(contractions='c', deletions='ab') True If a contraction set is not independent (or a deletion set not coindependent), @@ -27,9 +27,9 @@ sage: M = matroids.named_matroids.Fano() sage: M.rank('abf') 2 - sage: M / 'abf' == M / 'ab' \ 'f' + sage: M / 'abf' == (M / 'ab').delete('f') True - sage: M / 'abf' == M / 'af' \ 'b' + sage: M / 'abf' == (M / 'af').delete('b') True .. SEEALSO:: diff --git a/src/sage/misc/misc.py b/src/sage/misc/misc.py index a4f8ebb826e..936f279a690 100644 --- a/src/sage/misc/misc.py +++ b/src/sage/misc/misc.py @@ -560,12 +560,20 @@ def __rmul__(self, left): ....: A = random_matrix(ZZ, 4) sage: B = random_matrix(ZZ, 4) sage: temp = A * BackslashOperator() + doctest:...: + DeprecationWarning: the backslash operator has been deprecated + See https://github.com/sagemath/sage/issues/36394 for details. sage: temp.left is A True sage: X = temp * B + doctest:...: + DeprecationWarning: the backslash operator has been deprecated; use A.solve_right(B) instead + See https://github.com/sagemath/sage/issues/36394 for details. sage: A * X == B True """ + from sage.misc.superseded import deprecation + deprecation(36394, 'the backslash operator has been deprecated') self.left = left return self @@ -577,15 +585,26 @@ def __mul__(self, right): sage: A = matrix(RDF, 5, 5, 2) sage: b = vector(RDF, 5, range(5)) sage: v = A \ b + doctest:...: + DeprecationWarning: the backslash operator has been deprecated; use A.solve_right(B) instead + See https://github.com/sagemath/sage/issues/36394 for details. sage: v.zero_at(1e-19) # On at least one platform, we get a "negative zero" (0.0, 0.5, 1.0, 1.5, 2.0) sage: v = A._backslash_(b) + doctest:...: + DeprecationWarning: the backslash operator has been deprecated; use A.solve_right(B) instead + See https://github.com/sagemath/sage/issues/36394 for details. sage: v.zero_at(1e-19) (0.0, 0.5, 1.0, 1.5, 2.0) sage: v = A * BackslashOperator() * b + doctest:...: + DeprecationWarning: the backslash operator has been deprecated; use A.solve_right(B) instead + See https://github.com/sagemath/sage/issues/36394 for details. sage: v.zero_at(1e-19) (0.0, 0.5, 1.0, 1.5, 2.0) """ + from sage.misc.superseded import deprecation + deprecation(36394, 'the backslash operator has been deprecated') return self.left._backslash_(right) diff --git a/src/sage/tests/books/computational-mathematics-with-sagemath/linalg_doctest.py b/src/sage/tests/books/computational-mathematics-with-sagemath/linalg_doctest.py index 5b99bdfa6ac..4ab7d86d5d3 100644 --- a/src/sage/tests/books/computational-mathematics-with-sagemath/linalg_doctest.py +++ b/src/sage/tests/books/computational-mathematics-with-sagemath/linalg_doctest.py @@ -288,6 +288,8 @@ Sage example in ./linalg.tex, line 1855:: sage: A.solve_right(b) == A\b + doctest:...: DeprecationWarning: the backslash operator has been deprecated; use A.solve_right(B) instead + See https://github.com/sagemath/sage/issues/36394 for details. True Sage example in ./linalg.tex, line 1910:: diff --git a/src/sage/tests/books/computational-mathematics-with-sagemath/linsolve_doctest.py b/src/sage/tests/books/computational-mathematics-with-sagemath/linsolve_doctest.py index 7932167b41d..7c5b83423ea 100644 --- a/src/sage/tests/books/computational-mathematics-with-sagemath/linsolve_doctest.py +++ b/src/sage/tests/books/computational-mathematics-with-sagemath/linsolve_doctest.py @@ -49,7 +49,7 @@ sage: A = matrix(RDF, [[-1,2],[3,4]]) sage: b = vector(RDF, [2,3]) - sage: x = A\b; x + sage: x = A.solve_right(b); x (-0.20000000000000018, 0.9000000000000001) Sage example in ./linsolve.tex, line 666:: From f65ae6b45fd517ab0180e77eb0e92e3ce500803c Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 3 Oct 2023 17:50:42 -0700 Subject: [PATCH 042/216] Add more workarounds for setuptools_scm + --no-build-isolation --- src/setup.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/setup.py b/src/setup.py index f0dd4054bb7..0f28b20d6dc 100755 --- a/src/setup.py +++ b/src/setup.py @@ -11,6 +11,7 @@ import sys import time from setuptools import setup, find_namespace_packages +from setuptools.dist import Distribution from distutils import log import multiprocessing.pool @@ -33,6 +34,15 @@ import multiprocessing multiprocessing.set_start_method('fork', force=True) +# setuptools plugins considered harmful: +# If build isolation is not in use and setuptools_scm is installed, +# then its file_finders entry point is invoked, which we don't need. +# And with setuptools_scm 8, we get more trouble: +# LookupError: pyproject.toml does not contain a tool.setuptools_scm section +# LookupError: setuptools-scm was unable to detect version ... +# We just remove all handling of "setuptools.finalize_distribution_options" entry points. +Distribution._removed = staticmethod(lambda ep: True) + # ######################################################## # ## Set source directory # ######################################################## From 063896851ce74540bb0279baf6c58c92170c541a Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 4 Oct 2023 13:58:57 -0700 Subject: [PATCH 043/216] src/sage/misc/cython.py: Suppress a warning caused by setuptools_scm 8 --- src/sage/misc/cython.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/sage/misc/cython.py b/src/sage/misc/cython.py index 347b2e896d8..a33f9c361d5 100644 --- a/src/sage/misc/cython.py +++ b/src/sage/misc/cython.py @@ -415,6 +415,14 @@ def cython(filename, verbose=0, compile_message=False, # This emulates running "setup.py build" with the correct options dist = Distribution() + # setuptools plugins considered harmful: + # If build isolation is not in use and setuptools_scm is installed, + # then its file_finders entry point is invoked, which we don't need. + # And with setuptools_scm 8, we get more trouble: + # LookupError: pyproject.toml does not contain a tool.setuptools_scm section + # LookupError: setuptools-scm was unable to detect version ... + # We just remove all handling of "setuptools.finalize_distribution_options" entry points. + dist._removed = staticmethod(lambda ep: True) dist.ext_modules = [ext] dist.include_dirs = includes buildcmd = dist.get_command_obj("build") From 114a610bd241d44740534ec3c9d17d43c244983b Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 4 Oct 2023 15:15:21 -0700 Subject: [PATCH 044/216] pkgs/sage-*: Add setuptools_scm workaround to setup.py --- pkgs/sage-conf/setup.py | 11 +++++++++++ pkgs/sage-conf_pypi/setup.py | 11 +++++++++++ pkgs/sage-docbuild/setup.py | 10 ++++++++++ pkgs/sage-setup/setup.py | 10 ++++++++++ pkgs/sage-sws2rst/setup.py | 11 +++++++++++ 5 files changed, 53 insertions(+) diff --git a/pkgs/sage-conf/setup.py b/pkgs/sage-conf/setup.py index 8bf1ba938af..afa05966816 100644 --- a/pkgs/sage-conf/setup.py +++ b/pkgs/sage-conf/setup.py @@ -1,2 +1,13 @@ from setuptools import setup +from setuptools.dist import Distribution + +# setuptools plugins considered harmful: +# If build isolation is not in use and setuptools_scm is installed, +# then its file_finders entry point is invoked, which we don't need. +# And with setuptools_scm 8, we get more trouble: +# LookupError: pyproject.toml does not contain a tool.setuptools_scm section +# LookupError: setuptools-scm was unable to detect version ... +# We just remove all handling of "setuptools.finalize_distribution_options" entry points. +Distribution._removed = staticmethod(lambda ep: True) + setup() diff --git a/pkgs/sage-conf_pypi/setup.py b/pkgs/sage-conf_pypi/setup.py index a689f4d617b..9ebe45c12fe 100644 --- a/pkgs/sage-conf_pypi/setup.py +++ b/pkgs/sage-conf_pypi/setup.py @@ -5,12 +5,23 @@ import platform from setuptools import setup +from setuptools.dist import Distribution from distutils.command.build_scripts import build_scripts as distutils_build_scripts from setuptools.command.build_py import build_py as setuptools_build_py from setuptools.command.egg_info import egg_info as setuptools_egg_info from distutils.errors import (DistutilsSetupError, DistutilsModuleError, DistutilsOptionError) +# setuptools plugins considered harmful: +# If build isolation is not in use and setuptools_scm is installed, +# then its file_finders entry point is invoked, which we don't need. +# And with setuptools_scm 8, we get more trouble: +# LookupError: pyproject.toml does not contain a tool.setuptools_scm section +# LookupError: setuptools-scm was unable to detect version ... +# We just remove all handling of "setuptools.finalize_distribution_options" entry points. +Distribution._removed = staticmethod(lambda ep: True) + + class build_py(setuptools_build_py): def run(self): diff --git a/pkgs/sage-docbuild/setup.py b/pkgs/sage-docbuild/setup.py index beda28e8216..cd42da33ffe 100644 --- a/pkgs/sage-docbuild/setup.py +++ b/pkgs/sage-docbuild/setup.py @@ -1,5 +1,15 @@ #!/usr/bin/env python from setuptools import setup +from setuptools.dist import Distribution + +# setuptools plugins considered harmful: +# If build isolation is not in use and setuptools_scm is installed, +# then its file_finders entry point is invoked, which we don't need. +# And with setuptools_scm 8, we get more trouble: +# LookupError: pyproject.toml does not contain a tool.setuptools_scm section +# LookupError: setuptools-scm was unable to detect version ... +# We just remove all handling of "setuptools.finalize_distribution_options" entry points. +Distribution._removed = staticmethod(lambda ep: True) setup() diff --git a/pkgs/sage-setup/setup.py b/pkgs/sage-setup/setup.py index beda28e8216..cd42da33ffe 100644 --- a/pkgs/sage-setup/setup.py +++ b/pkgs/sage-setup/setup.py @@ -1,5 +1,15 @@ #!/usr/bin/env python from setuptools import setup +from setuptools.dist import Distribution + +# setuptools plugins considered harmful: +# If build isolation is not in use and setuptools_scm is installed, +# then its file_finders entry point is invoked, which we don't need. +# And with setuptools_scm 8, we get more trouble: +# LookupError: pyproject.toml does not contain a tool.setuptools_scm section +# LookupError: setuptools-scm was unable to detect version ... +# We just remove all handling of "setuptools.finalize_distribution_options" entry points. +Distribution._removed = staticmethod(lambda ep: True) setup() diff --git a/pkgs/sage-sws2rst/setup.py b/pkgs/sage-sws2rst/setup.py index 8bf1ba938af..afa05966816 100644 --- a/pkgs/sage-sws2rst/setup.py +++ b/pkgs/sage-sws2rst/setup.py @@ -1,2 +1,13 @@ from setuptools import setup +from setuptools.dist import Distribution + +# setuptools plugins considered harmful: +# If build isolation is not in use and setuptools_scm is installed, +# then its file_finders entry point is invoked, which we don't need. +# And with setuptools_scm 8, we get more trouble: +# LookupError: pyproject.toml does not contain a tool.setuptools_scm section +# LookupError: setuptools-scm was unable to detect version ... +# We just remove all handling of "setuptools.finalize_distribution_options" entry points. +Distribution._removed = staticmethod(lambda ep: True) + setup() From 1953d8f4d9af5aa63f8aac4d8502b9cde48ba179 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Thu, 5 Oct 2023 14:35:15 +0200 Subject: [PATCH 045/216] full pep8 in the modified function --- src/sage/matrix/special.py | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/sage/matrix/special.py b/src/sage/matrix/special.py index 54b1da99dd5..a1cc895364a 100644 --- a/src/sage/matrix/special.py +++ b/src/sage/matrix/special.py @@ -2552,28 +2552,28 @@ def random_rref_matrix(parent, num_pivots): # Keep track of the non-pivot columns by using the pivot_index, start at the first column to # the right of the initial pivot column, go until the first column to the left of the next # pivot column. - for pivot_index in range(num_pivots-1): - for non_pivot_column_index in range(pivots[pivot_index]+1, pivots[pivot_index+1]): + for pivot_index in range(num_pivots - 1): + for non_pivot_column_index in range(pivots[pivot_index] + 1, pivots[pivot_index + 1]): entry_generator1 = pd.RealDistribution("beta", [6, 4]) # Experimental distribution used to generate the values. - for non_pivot_column_entry in range(pivot_index+1): - sign1 = (2*randint(0,1)-1) - return_matrix[non_pivot_column_entry,non_pivot_column_index]=sign1*int(entry_generator1.get_random_element()*((1-non_pivot_column_entry/return_matrix.ncols())*7)) + for non_pivot_column_entry in range(pivot_index + 1): + sign1 = (2 * randint(0, 1) - 1) + return_matrix[non_pivot_column_entry, non_pivot_column_index] = sign1 * int(entry_generator1.get_random_element() * ((1 - non_pivot_column_entry / return_matrix.ncols()) * 7)) # Use index to fill entries of the columns to the right of the last pivot column. - for rest_non_pivot_column in range(pivots[num_pivots-1]+1,num_col): - entry_generator2=pd.RealDistribution("beta",[2.6,4]) + for rest_non_pivot_column in range(pivots[num_pivots - 1] + 1, num_col): + entry_generator2 = pd.RealDistribution("beta", [2.6, 4]) # experimental distribution to generate small values. for rest_entries in range(num_pivots): - sign2=(2*randint(0,1)-1) - return_matrix[rest_entries,rest_non_pivot_column]=sign2*int(entry_generator2.get_random_element()*5) + sign2 = (2 * randint(0, 1) - 1) + return_matrix[rest_entries, rest_non_pivot_column] = sign2 * int(entry_generator2.get_random_element() * 5) else: - for pivot_index in range(num_pivots-1): - for non_pivot_column_index in range(pivots[pivot_index]+1,pivots[pivot_index+1]): - for non_pivot_column_entry in range(pivot_index+1): - return_matrix[non_pivot_column_entry,non_pivot_column_index]=ring.random_element() - for rest_non_pivot_column in range(pivots[num_pivots-1]+1,num_col): + for pivot_index in range(num_pivots - 1): + for non_pivot_column_index in range(pivots[pivot_index] + 1, pivots[pivot_index + 1]): + for non_pivot_column_entry in range(pivot_index + 1): + return_matrix[non_pivot_column_entry, non_pivot_column_index] = ring.random_element() + for rest_non_pivot_column in range(pivots[num_pivots - 1] + 1, num_col): for rest_entries in range(num_pivots): - return_matrix[rest_entries,rest_non_pivot_column]=ring.random_element() + return_matrix[rest_entries, rest_non_pivot_column] = ring.random_element() return return_matrix From a370fd37742ea72a436f70640132880b2362b2b9 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 5 Oct 2023 09:42:30 -0700 Subject: [PATCH 046/216] build/pkgs/meson: Update to 1.2.2 --- build/pkgs/meson/checksums.ini | 6 +++--- build/pkgs/meson/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/meson/checksums.ini b/build/pkgs/meson/checksums.ini index ef8b1ec0b21..97e3fe2c251 100644 --- a/build/pkgs/meson/checksums.ini +++ b/build/pkgs/meson/checksums.ini @@ -1,5 +1,5 @@ tarball=meson-VERSION.tar.gz -sha1=087da0ecbc065bb40361ba683b55c20cb42a948a -md5=e3cc846536189aacd7d01858a45ca9af -cksum=4011973902 +sha1=39b8a4bff467fdaa5f9ee87e04715bd97a148378 +md5=702bfd8b0648521322d3f145a8fc70ea +cksum=399123386 upstream_url=https://pypi.io/packages/source/m/meson/meson-VERSION.tar.gz diff --git a/build/pkgs/meson/package-version.txt b/build/pkgs/meson/package-version.txt index 6085e946503..23aa8390630 100644 --- a/build/pkgs/meson/package-version.txt +++ b/build/pkgs/meson/package-version.txt @@ -1 +1 @@ -1.2.1 +1.2.2 From b74c2047cd2b0f26d2a7ee690410dc9bbc7fa85d Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 5 Oct 2023 09:43:49 -0700 Subject: [PATCH 047/216] build/pkgs/scipy: Update to 1.11.3 --- build/pkgs/scipy/checksums.ini | 6 +++--- build/pkgs/scipy/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/scipy/checksums.ini b/build/pkgs/scipy/checksums.ini index 7015206d1e7..a02413e57cd 100644 --- a/build/pkgs/scipy/checksums.ini +++ b/build/pkgs/scipy/checksums.ini @@ -1,5 +1,5 @@ tarball=scipy-VERSION.tar.gz -sha1=856f8ac8498751b72d678ef64b88e436d04a957d -md5=27baf613b6cf3f9600a05161f132151c -cksum=1656738318 +sha1=15905a54347bfbeb32f804bd7fa968b2d47881cc +md5=9f618e66c4b12b702793cdfd2b7b3847 +cksum=3174598552 upstream_url=https://pypi.io/packages/source/s/scipy/scipy-VERSION.tar.gz diff --git a/build/pkgs/scipy/package-version.txt b/build/pkgs/scipy/package-version.txt index ca7176690dd..0a5af26df3f 100644 --- a/build/pkgs/scipy/package-version.txt +++ b/build/pkgs/scipy/package-version.txt @@ -1 +1 @@ -1.11.2 +1.11.3 From 63a3116c7d5016f42ac071bece34a5973b7ff247 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 5 Oct 2023 09:44:52 -0700 Subject: [PATCH 048/216] build/pkgs/meson_python: Update to 0.14.0 --- build/pkgs/meson_python/checksums.ini | 6 +++--- build/pkgs/meson_python/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/meson_python/checksums.ini b/build/pkgs/meson_python/checksums.ini index da59c9577aa..7eb55561d9a 100644 --- a/build/pkgs/meson_python/checksums.ini +++ b/build/pkgs/meson_python/checksums.ini @@ -1,5 +1,5 @@ tarball=meson_python-VERSION.tar.gz -sha1=e52e84fcd84ea7dd8c11f464390786686a1be8e6 -md5=0db4483e30df43dbd465254be9c7db8a -cksum=1452585711 +sha1=ce9192048927ee724673f57d9881b6bee320ff82 +md5=27bc0a24d1f5e2e83236a73f0826eadb +cksum=530505556 upstream_url=https://pypi.io/packages/source/m/meson_python/meson_python-VERSION.tar.gz diff --git a/build/pkgs/meson_python/package-version.txt b/build/pkgs/meson_python/package-version.txt index 9beb74d490b..a803cc227fe 100644 --- a/build/pkgs/meson_python/package-version.txt +++ b/build/pkgs/meson_python/package-version.txt @@ -1 +1 @@ -0.13.2 +0.14.0 From 27f0b6388a00ef38bfd7a7479994997e680d2d4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Fri, 6 Oct 2023 19:08:41 +0200 Subject: [PATCH 049/216] suggested detail --- src/sage/combinat/partition.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/sage/combinat/partition.py b/src/sage/combinat/partition.py index 1d0449b3d1e..488315254ef 100644 --- a/src/sage/combinat/partition.py +++ b/src/sage/combinat/partition.py @@ -4201,8 +4201,9 @@ def zero_one_sequence(self): sage: all(Partitions().from_zero_one(mu.zero_one_sequence()) == mu for n in range(10) for mu in Partitions(n)) True """ - tmp = [self[i] - i for i in range(len(self))] - return [Integer(i not in tmp) for i in range(-len(self) + 1, self.get_part(0) + 1)] + tmp = set(self[i] - i for i in range(len(self))) + return [Integer(i not in tmp) + for i in range(-len(self) + 1, self.get_part(0) + 1)] def core(self, length): r""" From 6485da7b387c553a1fb170c31665d59483606d77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Fri, 6 Oct 2023 20:26:01 +0200 Subject: [PATCH 050/216] various details in schemes --- src/sage/schemes/affine/affine_subscheme.py | 2 +- src/sage/schemes/curves/closed_point.py | 2 +- src/sage/schemes/curves/curve.py | 2 +- src/sage/schemes/elliptic_curves/cm.py | 2 +- src/sage/schemes/elliptic_curves/ell_number_field.py | 2 +- src/sage/schemes/elliptic_curves/ell_point.py | 4 ++-- src/sage/schemes/elliptic_curves/ell_rational_field.py | 2 +- src/sage/schemes/elliptic_curves/heegner.py | 3 --- src/sage/schemes/elliptic_curves/isogeny_class.py | 8 ++++---- src/sage/schemes/elliptic_curves/period_lattice.py | 2 +- src/sage/schemes/hyperelliptic_curves/constructor.py | 2 +- src/sage/schemes/hyperelliptic_curves/jacobian_generic.py | 2 +- src/sage/schemes/plane_conics/con_number_field.py | 4 ++-- src/sage/schemes/plane_conics/con_rational_field.py | 8 ++++---- src/sage/schemes/projective/projective_morphism.py | 6 ++++-- src/sage/schemes/riemann_surfaces/riemann_surface.py | 2 +- 16 files changed, 26 insertions(+), 27 deletions(-) diff --git a/src/sage/schemes/affine/affine_subscheme.py b/src/sage/schemes/affine/affine_subscheme.py index ed125a60193..8baee490b88 100644 --- a/src/sage/schemes/affine/affine_subscheme.py +++ b/src/sage/schemes/affine/affine_subscheme.py @@ -484,7 +484,7 @@ def multiplicity(self, P): sage: X.multiplicity(Q) # needs sage.libs.singular 1 """ - if not self.base_ring() in Fields(): + if self.base_ring() not in Fields(): raise TypeError("subscheme must be defined over a field") # check whether P is a point on this subscheme diff --git a/src/sage/schemes/curves/closed_point.py b/src/sage/schemes/curves/closed_point.py index 0b5952559c1..147d60b200a 100644 --- a/src/sage/schemes/curves/closed_point.py +++ b/src/sage/schemes/curves/closed_point.py @@ -418,7 +418,7 @@ def affine(self, i=None): ideal = self.prime_ideal() if i is None: for j in range(P.ngens()): - if not P.gen(j) in ideal: + if P.gen(j) not in ideal: i = j break else: diff --git a/src/sage/schemes/curves/curve.py b/src/sage/schemes/curves/curve.py index 0af6fff803b..79fcc820618 100644 --- a/src/sage/schemes/curves/curve.py +++ b/src/sage/schemes/curves/curve.py @@ -340,7 +340,7 @@ def singular_points(self, F=None): (b^6 : -b^6 : 1)] """ if F is None: - if not self.base_ring() in Fields(): + if self.base_ring() not in Fields(): raise TypeError("curve must be defined over a field") F = self.base_ring() elif F not in Fields(): diff --git a/src/sage/schemes/elliptic_curves/cm.py b/src/sage/schemes/elliptic_curves/cm.py index 09a6b63f402..03acc69e732 100644 --- a/src/sage/schemes/elliptic_curves/cm.py +++ b/src/sage/schemes/elliptic_curves/cm.py @@ -113,7 +113,7 @@ def hilbert_class_polynomial(D, algorithm=None): D = Integer(D) if D >= 0: raise ValueError("D (=%s) must be negative" % D) - if not (D % 4 in [0, 1]): + if (D % 4) not in [0, 1]: raise ValueError("D (=%s) must be a discriminant" % D) if algorithm == "arb": diff --git a/src/sage/schemes/elliptic_curves/ell_number_field.py b/src/sage/schemes/elliptic_curves/ell_number_field.py index 54777488572..d2f332e4569 100644 --- a/src/sage/schemes/elliptic_curves/ell_number_field.py +++ b/src/sage/schemes/elliptic_curves/ell_number_field.py @@ -2510,7 +2510,7 @@ def real_components(self, embedding): ValueError: invalid embedding specified: should have domain ... """ try: - if not embedding.domain() is self.base_field(): + if embedding.domain() is not self.base_field(): raise ValueError("invalid embedding specified: should have domain {}".format(self.base_field())) if not isinstance(embedding.codomain(), sage.rings.abc.RealField): raise ValueError("invalid embedding specified: should be real") diff --git a/src/sage/schemes/elliptic_curves/ell_point.py b/src/sage/schemes/elliptic_curves/ell_point.py index 774ad2d383a..24908b9743e 100644 --- a/src/sage/schemes/elliptic_curves/ell_point.py +++ b/src/sage/schemes/elliptic_curves/ell_point.py @@ -1931,7 +1931,7 @@ def tate_pairing(self, Q, n, k, q=None): P = self E = P.curve() - if not Q.curve() is E: + if Q.curve() is not E: raise ValueError("Points must both be on the same curve") K = E.base_ring() @@ -2139,7 +2139,7 @@ def ate_pairing(self, Q, n, k, t, q=None): # check for same curve E = P.curve() O = E(0) - if not Q.curve() is E: + if Q.curve() is not E: raise ValueError("Points must both be on the same curve") # set q to be the order of the base field diff --git a/src/sage/schemes/elliptic_curves/ell_rational_field.py b/src/sage/schemes/elliptic_curves/ell_rational_field.py index 47dc2fc2a64..27e52973afd 100644 --- a/src/sage/schemes/elliptic_curves/ell_rational_field.py +++ b/src/sage/schemes/elliptic_curves/ell_rational_field.py @@ -4987,7 +4987,7 @@ def is_isogenous(self, other, proof=True, maxp=200): """ if not is_EllipticCurve(other): raise ValueError("Second argument is not an Elliptic Curve.") - if not other.base_field() is QQ: + if other.base_field() is not QQ: raise ValueError("If first argument is an elliptic curve over QQ then the second argument must be also.") if self.is_isomorphic(other): diff --git a/src/sage/schemes/elliptic_curves/heegner.py b/src/sage/schemes/elliptic_curves/heegner.py index 058b2f84669..a377c02d5cb 100644 --- a/src/sage/schemes/elliptic_curves/heegner.py +++ b/src/sage/schemes/elliptic_curves/heegner.py @@ -118,14 +118,11 @@ from sage.misc.verbose import verbose from sage.modular.modsym.p1list import P1List from sage.rings.complex_double import CDF -from sage.rings.complex_mpfr import ComplexField from sage.rings.factorint import factor_trial_division from sage.rings.finite_rings.finite_field_constructor import FiniteField as GF from sage.rings.finite_rings.integer_mod_ring import IntegerModRing as Integers from sage.rings.integer_ring import ZZ -from sage.rings.number_field.number_field import QuadraticField from sage.rings.rational_field import QQ -from sage.rings.real_mpfr import RealField from sage.quadratic_forms.binary_qf import BinaryQF from sage.quadratic_forms.binary_qf import BinaryQF_reduced_representatives from sage.rings.number_field.number_field_element_base import NumberFieldElement_base diff --git a/src/sage/schemes/elliptic_curves/isogeny_class.py b/src/sage/schemes/elliptic_curves/isogeny_class.py index 84404c28b76..ed05e1760fa 100644 --- a/src/sage/schemes/elliptic_curves/isogeny_class.py +++ b/src/sage/schemes/elliptic_curves/isogeny_class.py @@ -406,17 +406,17 @@ def graph(self): """ from sage.graphs.graph import Graph - if not self.E.base_field() is QQ: + if self.E.base_field() is not QQ: M = self.matrix(fill=False) n = len(self) G = Graph(M, format='weighted_adjacency_matrix') D = dict([(v,self.curves[v]) for v in G.vertices(sort=False)]) G.set_vertices(D) - if self._qfmat: # i.e. self.E.has_rational_cm(): + if self._qfmat: # i.e. self.E.has_rational_cm(): for i in range(n): for j in range(n): - if M[i,j]: - G.set_edge_label(i,j,str(self._qfmat[i][j])) + if M[i, j]: + G.set_edge_label(i, j, str(self._qfmat[i][j])) G.relabel(list(range(1, n + 1))) return G diff --git a/src/sage/schemes/elliptic_curves/period_lattice.py b/src/sage/schemes/elliptic_curves/period_lattice.py index fe07917abaa..41483a48377 100644 --- a/src/sage/schemes/elliptic_curves/period_lattice.py +++ b/src/sage/schemes/elliptic_curves/period_lattice.py @@ -1707,7 +1707,7 @@ def elliptic_logarithm(self, P, prec=None, reduce=True): sage: L.elliptic_logarithm(P, prec=1000) 1.17058357737548897849026170185581196033579563441850967539191867385734983296504066660506637438866628981886518901958717288150400849746892393771983141354014895386251320571643977497740116710952913769943240797618468987304985625823413440999754037939123032233879499904283600304184828809773650066658885672885 - 1.13513899565966043682474529757126359416758251309237866586896869548539516543734207347695898664875799307727928332953834601460994992792519799260968053875387282656993476491590607092182964878750169490985439873220720963653658829712494879003124071110818175013453207439440032582917366703476398880865439217473*I """ - if not P.curve() is self.E: + if P.curve() is not self.E: raise ValueError("Point is on the wrong curve") if prec is None: prec = RealField().precision() diff --git a/src/sage/schemes/hyperelliptic_curves/constructor.py b/src/sage/schemes/hyperelliptic_curves/constructor.py index de93cc7e371..776b49f394e 100644 --- a/src/sage/schemes/hyperelliptic_curves/constructor.py +++ b/src/sage/schemes/hyperelliptic_curves/constructor.py @@ -229,7 +229,7 @@ def HyperellipticCurve(f, h=0, names=None, PP=None, check_squarefree=True): should_be_coprime = [h, f*h.derivative()**2+f.derivative()**2] else: # characteristic not 2 - if not F.degree() in [2*g+1, 2*g+2]: + if F.degree() not in [2*g+1, 2*g+2]: raise ValueError("Not a hyperelliptic curve: " "highly singular at infinity.") should_be_coprime = [F, F.derivative()] diff --git a/src/sage/schemes/hyperelliptic_curves/jacobian_generic.py b/src/sage/schemes/hyperelliptic_curves/jacobian_generic.py index 8e2df486769..1d3b0fd2763 100644 --- a/src/sage/schemes/hyperelliptic_curves/jacobian_generic.py +++ b/src/sage/schemes/hyperelliptic_curves/jacobian_generic.py @@ -5,7 +5,7 @@ # **************************************************************************** # Copyright (C) 2006 David Kohel # Distributed under the terms of the GNU General Public License (GPL) -# http://www.gnu.org/licenses/ +# https://www.gnu.org/licenses/ # **************************************************************************** from sage.rings.integer import Integer diff --git a/src/sage/schemes/plane_conics/con_number_field.py b/src/sage/schemes/plane_conics/con_number_field.py index 19be6d237a8..af0bdc5f0e0 100644 --- a/src/sage/schemes/plane_conics/con_number_field.py +++ b/src/sage/schemes/plane_conics/con_number_field.py @@ -442,10 +442,10 @@ def local_obstructions(self, finite=True, infinite=True, read_cache=True): for a in self.symmetric_matrix().list(): if a != 0: for f in O.fractional_ideal(a).factor(): - if f[1] < 0 and not f[0] in candidates: + if f[1] < 0 and f[0] not in candidates: candidates.append(f[0]) for f in O.fractional_ideal(2 * self.determinant()).factor(): - if f[1] > 0 and not f[0] in candidates: + if f[1] > 0 and f[0] not in candidates: candidates.append(f[0]) for b in candidates: if not self.is_locally_solvable(b): diff --git a/src/sage/schemes/plane_conics/con_rational_field.py b/src/sage/schemes/plane_conics/con_rational_field.py index 46de65132b5..c6c76df0820 100644 --- a/src/sage/schemes/plane_conics/con_rational_field.py +++ b/src/sage/schemes/plane_conics/con_rational_field.py @@ -297,11 +297,11 @@ def local_obstructions(self, finite=True, infinite=True, read_cache=True): for a in self.symmetric_matrix().list(): if a != 0: for f in a.factor(): - if f[1] < 0 and not f[0] in candidates: + if f[1] < 0 and f[0] not in candidates: candidates.append(f[0]) - for f in (2 * self.determinant()).factor(): - if f[1] > 0 and not f[0] in candidates: - candidates.append(f[0]) + for f0, f1 in (2 * self.determinant()).factor(): + if f1 > 0 and f0 not in candidates: + candidates.append(f0) for b in candidates: if not self.is_locally_solvable(b): obs1.append(b) diff --git a/src/sage/schemes/projective/projective_morphism.py b/src/sage/schemes/projective/projective_morphism.py index 5ba47f00afa..c0f3fb20fdf 100644 --- a/src/sage/schemes/projective/projective_morphism.py +++ b/src/sage/schemes/projective/projective_morphism.py @@ -2482,9 +2482,11 @@ def representatives(self): R = S.quotient_ring(X.defining_ideal().change_ring(S)) if R is S: # true when the defining ideal is zero - lift = lambda x: x.numerator() + def lift(x): + return x.numerator() else: # R is an ordinary quotient ring - lift = lambda x: x.lift() + def lift(x): + return x.lift() F = [R(f) for f in self.defining_polynomials()] n = len(F) diff --git a/src/sage/schemes/riemann_surfaces/riemann_surface.py b/src/sage/schemes/riemann_surfaces/riemann_surface.py index 14599021c5d..3166cbf11e3 100644 --- a/src/sage/schemes/riemann_surfaces/riemann_surface.py +++ b/src/sage/schemes/riemann_surfaces/riemann_surface.py @@ -712,7 +712,7 @@ def __init__( combined_discriminant = lcm(discriminants)(*self._R.gens()) self._differentials_branch_locus = [] for x in combined_discriminant.factor(): - if not x[0] in existing_factors: + if x[0] not in existing_factors: self._differentials_branch_locus += self._CCz( x[0](self._CCz.gen(), 0) ).roots(multiplicities=False) From 08ae5d3918487faf438538fed57953533c33b61f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Sat, 7 Oct 2023 14:23:24 +0200 Subject: [PATCH 051/216] fix for E702 in pyx outside rings --- src/sage/coding/binary_code.pyx | 86 +++++++++++++------ .../perm_gps/partn_ref/refinement_binary.pyx | 41 ++++++--- src/sage/matrix/matrix2.pyx | 26 ++++-- .../polynomial/polynomial_complex_arb.pyx | 17 +++- 4 files changed, 119 insertions(+), 51 deletions(-) diff --git a/src/sage/coding/binary_code.pyx b/src/sage/coding/binary_code.pyx index c3f9433d07f..407fb43fcca 100644 --- a/src/sage/coding/binary_code.pyx +++ b/src/sage/coding/binary_code.pyx @@ -1206,7 +1206,6 @@ cdef class BinaryCode: combination ^= (1 << j) word ^= self.basis[j] - cpdef int put_in_std_form(self): """ Put the code in binary form, which is defined by an identity matrix on @@ -1225,7 +1224,6 @@ cdef class BinaryCode: Binary [6,2] linear code, generator matrix [101011] [010111] - """ cdef codeword swap, current = 1, pivots = 0 cdef int i, j, k, row = 0 @@ -1261,6 +1259,7 @@ cdef class BinaryCode: self._apply_permutation_to_basis(perm) self._update_words_from_basis() + cdef class OrbitPartition: """ Structure which keeps track of which vertices are equivalent @@ -2770,7 +2769,8 @@ cdef class PartitionStack: j = 0 if alpha[m] & flag: while j < self_ncols: - i = j; s = 0 + i = j + s = 0 invariant += 8 while True: self_col_degs[i-j] = self.col_degree(CG, self_col_ents[i], alpha[m]^flag, k) @@ -2800,7 +2800,8 @@ cdef class PartitionStack: j = i else: while j < self.nwords: - i = j; s = 0 + i = j + s = 0 invariant += 64 while True: self_wd_degs[i-j] = self.wd_degree(CG, self_wd_ents[i], alpha[m], k, ham_wts) @@ -3430,7 +3431,9 @@ cdef class BinaryCodeClassifier: alpha[1] = nu.flag nu.refine(k, alpha, 2, C, ham_wts) if nu.sat_225(k): hh = k - if nu.is_discrete(k): state = 18; continue + if nu.is_discrete(k): + state = 18 + continue # store the first smallest nontrivial cell in W[k], and set v[k] # equal to its minimum element @@ -3448,7 +3451,9 @@ cdef class BinaryCodeClassifier: alpha[0] = nu.split_vertex(v[k-1], k) Lambda[k] = nu.refine(k, alpha, 1, C, ham_wts) # store the invariant to Lambda[k] # only if this is the first time moving down the search tree: - if h == -1: state = 5; continue + if h == -1: + state = 5 + continue # update hzf__h_zeta if hzf__h_zeta == k-1 and Lambda[k] == zf__Lambda_zeta[k]: hzf__h_zeta = k @@ -3478,7 +3483,9 @@ cdef class BinaryCodeClassifier: else: state = 6 elif state == 4: # at this point we have -not- ruled out the presence of automorphisms - if nu.is_discrete(k): state = 7; continue # we have a terminal node, so process it + if nu.is_discrete(k): + state = 7 + continue # we have a terminal node, so process it # otherwise, prepare to split out another column: # store the first smallest nontrivial cell in W[k], and set v[k] @@ -3521,7 +3528,9 @@ cdef class BinaryCodeClassifier: if hb > k:# update hb since we are backtracking hb = k # if j == hh, then all nodes lower than our current position are equivalent, so bail out - if j == hh: state = 13; continue + if j == hh: + state = 13 + continue # recall hh: the height of the oldest ancestor of zeta for which Lemma 2.25 is # satisfied, which implies that all terminal nodes descended from there are equivalent. @@ -3536,11 +3545,15 @@ cdef class BinaryCodeClassifier: elif state == 7: # we have just arrived at a terminal node of the search tree T(G, Pi) # if this is the first terminal node, go directly to 18, to # process zeta - if h == -1: state = 18; continue + if h == -1: + state = 18 + continue # hzf is the extremal height of ancestors of both nu and zeta, so if k < hzf, nu is not # equivalent to zeta, i.e. there is no automorphism to discover. - if k < hzf__h_zeta: state = 8; continue + if k < hzf__h_zeta: + state = 8 + continue nu.get_permutation(zeta, word_gamma, col_gamma) @@ -3553,18 +3566,26 @@ cdef class BinaryCodeClassifier: elif state == 8: # we have just ruled out the presence of automorphism and have not yet # considered whether nu improves on rho # if qzb < 0, then rho already has larger indicator tuple - if qzb < 0: state = 6; continue + if qzb < 0: + state = 6 + continue # if Lambda[k] > zb[k] or nu is shorter than rho, then we have an improvement for rho - if (qzb > 0) or (k < k_rho): state = 9; continue + if (qzb > 0) or (k < k_rho): + state = 9 + continue # now Lambda[k] == zb[k] and k == k_rho, so we appeal to an enumeration: j = nu.cmp(rho, C) # if C(nu) > C(rho), we have a new label, goto 9 - if j > 0: state = 9; continue + if j > 0: + state = 9 + continue # if C(nu) < C(rho), no new label, goto 6 - if j < 0: state = 6; continue + if j < 0: + state = 6 + continue # if C(nu) == C(rho), get the automorphism and goto 10 rho.get_permutation(nu, word_gamma, col_gamma) @@ -3627,7 +3648,9 @@ cdef class BinaryCodeClassifier: # j stores whether anything happened or not- if not, then the automorphism we have # discovered is already in the subgroup spanned by the generators we have output - if not j: state = 11; continue + if not j: + state = 11 + continue # otherwise, we have a new generator, so record it: self.record_automorphism(col_gamma, ncols) @@ -3641,10 +3664,12 @@ cdef class BinaryCodeClassifier: if tvc & nu.flag: i = tvc^nu.flag if Theta.wd_min_cell_rep[Theta.wd_find(i)] == i: - state = 11; continue + state = 11 + continue else: if Theta.col_min_cell_rep[Theta.col_find(tvc)] == tvc: - state = 11; continue + state = 11 + continue # Otherwise, proceed to where zeta meets nu: k = h @@ -3675,11 +3700,17 @@ cdef class BinaryCodeClassifier: state = 13 elif state == 13: # hub state - if k == -1: state = -1; continue # exit point + if k == -1: + state = -1 + continue # exit point - if k > h: state = 17; continue # we are still on the same principal branch from zeta + if k > h: + state = 17 + continue # we are still on the same principal branch from zeta - if k == h: state = 14; continue # update the stabilizer index and check for new splits, + if k == h: + state = 14 + continue # update the stabilizer index and check for new splits, # since we have returned to a partition of zeta # otherwise k < h, hence we have just backtracked up zeta, and are one level closer to done h = k @@ -3719,7 +3750,8 @@ cdef class BinaryCodeClassifier: v[k] = i^nu.flag else: # there is no new split at this level - state = 16; continue + state = 16 + continue # new split column better be a minimal representative in Theta, or wasted effort if Theta.wd_min_cell_rep[Theta.wd_find(i)] == i: state = 15 @@ -3733,7 +3765,8 @@ cdef class BinaryCodeClassifier: v[k] = i else: # there is no new split at this level - state = 16; continue + state = 16 + continue # new split column better be a minimal representative in Theta, or wasted effort if Theta.col_min_cell_rep[Theta.col_find(v[k])] == v[k]: state = 15 @@ -3760,7 +3793,8 @@ cdef class BinaryCodeClassifier: i = W[jj] j = ham_wts[i & 65535] + ham_wts[(i >> 16) & 65535] else: - i = 0; j = 0 + i = 0 + j = 0 ii = self.radix while i*ii < nwords: iii = W[jj+1+i] @@ -3812,7 +3846,8 @@ cdef class BinaryCodeClassifier: if (1 << i%self.radix) & W[jjj+1+i/self.radix]: break if i < nwords: v[k] = i^nu.flag - state = 15; continue + state = 15 + continue else: i = v[k] while i < ncols: @@ -3820,7 +3855,8 @@ cdef class BinaryCodeClassifier: if (1 << i) & W[jjj]: break if i < ncols: v[k] = i - state = 15; continue + state = 15 + continue k -= 1 state = 13 diff --git a/src/sage/groups/perm_gps/partn_ref/refinement_binary.pyx b/src/sage/groups/perm_gps/partn_ref/refinement_binary.pyx index 56e4a062d02..bf69d2c686f 100644 --- a/src/sage/groups/perm_gps/partn_ref/refinement_binary.pyx +++ b/src/sage/groups/perm_gps/partn_ref/refinement_binary.pyx @@ -93,9 +93,12 @@ cdef class LinearBinaryCodeStruct(BinaryCodeStruct): bitset_free(&self.basis[j]) memerr = 1 if memerr: - sig_free(self.basis); sig_free(self.scratch_bitsets) - sig_free(self.alpha_is_wd); PS_dealloc(self.word_ps) - sig_free(self.alpha); sig_free(self.scratch) + sig_free(self.basis) + sig_free(self.scratch_bitsets) + sig_free(self.alpha_is_wd) + PS_dealloc(self.word_ps) + sig_free(self.alpha) + sig_free(self.scratch) raise MemoryError else: bitset_zero(self.alpha_is_wd) @@ -349,9 +352,12 @@ cdef class LinearBinaryCodeStruct(BinaryCodeStruct): bitset_free(&self.scratch_bitsets[j]) for j from 0 <= j < self.dimension: bitset_free(&self.basis[j]) - sig_free(self.basis); sig_free(self.scratch_bitsets) - sig_free(self.alpha_is_wd); PS_dealloc(self.word_ps) - sig_free(self.alpha); sig_free(self.scratch) + sig_free(self.basis) + sig_free(self.scratch_bitsets) + sig_free(self.alpha_is_wd) + PS_dealloc(self.word_ps) + sig_free(self.alpha) + sig_free(self.scratch) if self.output is not NULL: deallocate_agcl_output(self.output) @@ -433,9 +439,12 @@ cdef class NonlinearBinaryCodeStruct(BinaryCodeStruct): bitset_free(&self.words[j]) memerr = 1 if memerr: - sig_free(self.words); sig_free(self.scratch_bitsets) - sig_free(self.alpha_is_wd); PS_dealloc(self.word_ps) - sig_free(self.alpha); sig_free(self.scratch) + sig_free(self.words) + sig_free(self.scratch_bitsets) + sig_free(self.alpha_is_wd) + PS_dealloc(self.word_ps) + sig_free(self.alpha) + sig_free(self.scratch) raise MemoryError else: bitset_zero(self.alpha_is_wd) @@ -456,9 +465,12 @@ cdef class NonlinearBinaryCodeStruct(BinaryCodeStruct): bitset_free(&self.scratch_bitsets[j]) for j from 0 <= j < self.nwords: bitset_free(&self.words[j]) - sig_free(self.words); sig_free(self.scratch_bitsets) - sig_free(self.alpha_is_wd); PS_dealloc(self.word_ps) - sig_free(self.alpha); sig_free(self.scratch) + sig_free(self.words) + sig_free(self.scratch_bitsets) + sig_free(self.alpha_is_wd) + PS_dealloc(self.word_ps) + sig_free(self.alpha) + sig_free(self.scratch) if self.output is not NULL: deallocate_agcl_output(self.output) @@ -468,8 +480,9 @@ cdef class NonlinearBinaryCodeStruct(BinaryCodeStruct): storing results to self. INPUT: - partition -- an optional list of lists partition of the columns. - default is the unit partition. + + - partition -- an optional list of lists partition of the columns. + default is the unit partition. EXAMPLES:: diff --git a/src/sage/matrix/matrix2.pyx b/src/sage/matrix/matrix2.pyx index 86aca6e00d8..efd69d6935d 100644 --- a/src/sage/matrix/matrix2.pyx +++ b/src/sage/matrix/matrix2.pyx @@ -3642,7 +3642,8 @@ cdef class Matrix(Matrix1): for i from 0 <= i <= n: # Finally, set v[i] = c[n,i] o = c.get_unsafe(n,i) - Py_INCREF(o); PyList_SET_ITEM(v, i, o) + Py_INCREF(o) + PyList_SET_ITEM(v, i, o) R = self._base_ring[var] # polynomial ring over the base ring return R(v) @@ -4554,7 +4555,8 @@ cdef class Matrix(Matrix1): # Third: generic first, if requested explicitly # then try specialized class methods, and finally # delegate to ad-hoc methods in greater generality - M = None; format = '' + M = None + format = '' if algorithm == 'generic': format, M = self._right_kernel_matrix_over_field() @@ -6018,7 +6020,8 @@ cdef class Matrix(Matrix1): sage: t.charpoly() # needs sage.libs.pari x^3 - 12*x^2 - 18*x """ - i = int(i); t=int(t) + i = int(i) + t=int(t) if self.nrows() != self.ncols(): raise ArithmeticError("self must be a square matrix") n = self.nrows() @@ -11028,7 +11031,8 @@ cdef class Matrix(Matrix1): R = self.base_ring() if isinstance(R, (sage.rings.abc.RealDoubleField, sage.rings.abc.ComplexDoubleField)): Q, R = self.transpose().QR() - m = R.nrows(); n = R.ncols() + m = R.nrows() + n = R.ncols() if m > n: Q = Q[0:m, 0:n] R = R[0:n, 0:n] @@ -14243,8 +14247,11 @@ cdef class Matrix(Matrix1): # a 1x1 pivot, but this time we need to swap # rows/columns k and r. d.append( one_by_one_space(A_rr) ) - A.swap_columns_c(k,r); A.swap_rows_c(k,r) - p_k = p[k]; p[k] = p[r]; p[r] = p_k + A.swap_columns_c(k, r) + A.swap_rows_c(k, r) + p_k = p[k] + p[k] = p[r] + p[r] = p_k _block_ldlt_pivot1x1(A,k) k += 1 continue @@ -14253,8 +14260,11 @@ cdef class Matrix(Matrix1): # or Step (6) in B&K, where we perform a 2x2 pivot. See # pivot1x1() for an explanation of why it's OK to permute # the entries of "L" here as well. - A.swap_columns_c(k+1,r); A.swap_rows_c(k+1,r) - p_k = p[k+1]; p[k+1] = p[r]; p[r] = p_k + A.swap_columns_c(k+1, r) + A.swap_rows_c(k+1, r) + p_k = p[k+1] + p[k+1] = p[r] + p[r] = p_k # The top-left 2x2 submatrix (starting at position k,k) is # now our pivot. diff --git a/src/sage/rings/polynomial/polynomial_complex_arb.pyx b/src/sage/rings/polynomial/polynomial_complex_arb.pyx index 57c1a52ede4..985f1dec394 100644 --- a/src/sage/rings/polynomial/polynomial_complex_arb.pyx +++ b/src/sage/rings/polynomial/polynomial_complex_arb.pyx @@ -36,6 +36,7 @@ from sage.structure.element import coerce_binop cdef inline long prec(Polynomial_complex_arb pol): return pol._parent._base._prec + cdef class Polynomial_complex_arb(Polynomial): r""" Wrapper for `Arb `_ polynomials of type @@ -152,21 +153,27 @@ cdef class Polynomial_complex_arb(Polynomial): if isinstance(x, list): lst = x length = len(lst) - sig_on(); acb_poly_fit_length(self._poly, length); sig_off() + sig_on() + acb_poly_fit_length(self._poly, length) + sig_off() for i in range(length): ball = Coeff(lst[i]) acb_poly_set_coeff_acb(self._poly, i, ball.value) elif isinstance(x, tuple): tpl = x length = len(tpl) - sig_on(); acb_poly_fit_length(self._poly, length); sig_off() + sig_on() + acb_poly_fit_length(self._poly, length) + sig_off() for i in range(length): ball = Coeff(tpl[i]) acb_poly_set_coeff_acb(self._poly, i, ball.value) elif isinstance(x, Polynomial): pol = x length = pol.degree() + 1 - sig_on(); acb_poly_fit_length(self._poly, length); sig_off() + sig_on() + acb_poly_fit_length(self._poly, length) + sig_off() for i in range(length): ball = Coeff(pol.get_unsafe(i)) acb_poly_set_coeff_acb(self._poly, i, ball.value) @@ -176,7 +183,9 @@ cdef class Polynomial_complex_arb(Polynomial): acb_poly_zero(self._poly) else: length = max(int(i) for i in dct) + 1 - sig_on(); acb_poly_fit_length(self._poly, length); sig_off() + sig_on() + acb_poly_fit_length(self._poly, length) + sig_off() for i, c in dct.iteritems(): ball = Coeff(c) acb_poly_set_coeff_acb(self._poly, i, ball.value) From 1ab93a50c6c18e38ffe4d9c19f1b26d723c44957 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Sun, 8 Oct 2023 08:42:49 +0200 Subject: [PATCH 052/216] suggested details --- src/sage/coding/binary_code.pyx | 7 +++---- src/sage/groups/perm_gps/partn_ref/refinement_binary.pyx | 4 ++-- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/sage/coding/binary_code.pyx b/src/sage/coding/binary_code.pyx index 407fb43fcca..fba66d7c690 100644 --- a/src/sage/coding/binary_code.pyx +++ b/src/sage/coding/binary_code.pyx @@ -3666,10 +3666,9 @@ cdef class BinaryCodeClassifier: if Theta.wd_min_cell_rep[Theta.wd_find(i)] == i: state = 11 continue - else: - if Theta.col_min_cell_rep[Theta.col_find(tvc)] == tvc: - state = 11 - continue + elif Theta.col_min_cell_rep[Theta.col_find(tvc)] == tvc: + state = 11 + continue # Otherwise, proceed to where zeta meets nu: k = h diff --git a/src/sage/groups/perm_gps/partn_ref/refinement_binary.pyx b/src/sage/groups/perm_gps/partn_ref/refinement_binary.pyx index bf69d2c686f..f81ce62060f 100644 --- a/src/sage/groups/perm_gps/partn_ref/refinement_binary.pyx +++ b/src/sage/groups/perm_gps/partn_ref/refinement_binary.pyx @@ -477,11 +477,11 @@ cdef class NonlinearBinaryCodeStruct(BinaryCodeStruct): def run(self, partition=None): """ Perform the canonical labeling and automorphism group computation, - storing results to self. + storing results to ``self``. INPUT: - - partition -- an optional list of lists partition of the columns. + - ``partition`` -- an optional list of lists partition of the columns. default is the unit partition. EXAMPLES:: From d2230403271f79545aac840777cd034a8d172cad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Sun, 8 Oct 2023 10:59:39 +0200 Subject: [PATCH 053/216] another detail --- 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 efd69d6935d..730499e69d4 100644 --- a/src/sage/matrix/matrix2.pyx +++ b/src/sage/matrix/matrix2.pyx @@ -6021,7 +6021,7 @@ cdef class Matrix(Matrix1): x^3 - 12*x^2 - 18*x """ i = int(i) - t=int(t) + t = int(t) if self.nrows() != self.ncols(): raise ArithmeticError("self must be a square matrix") n = self.nrows() From 143a7afc6584d1e2329d70699a8d8c9889b87865 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Sun, 8 Oct 2023 17:06:58 +0200 Subject: [PATCH 054/216] fix and activate E225 and E228 --- .vscode/settings.json | 2 +- src/sage/databases/cremona.py | 8 +- src/sage/databases/db_class_polynomials.py | 2 +- src/sage/databases/knotinfo_db.py | 38 +++---- src/sage/databases/sql_db.py | 98 ++++++++--------- src/sage/doctest/control.py | 28 ++--- src/sage/doctest/parsing.py | 2 +- src/sage/doctest/reporting.py | 46 ++++---- src/sage/doctest/util.py | 8 +- src/sage/functions/jacobi.py | 70 ++++++------ src/sage/functions/other.py | 6 +- src/sage/functions/piecewise.py | 18 +-- src/sage/graphs/generators/basic.py | 4 +- src/sage/graphs/partial_cube.py | 2 +- src/sage/groups/abelian_gps/abelian_aut.py | 2 +- src/sage/groups/abelian_gps/abelian_group.py | 12 +- .../groups/abelian_gps/abelian_group_gap.py | 2 +- src/sage/groups/abelian_gps/element_base.py | 4 +- .../additive_abelian_group.py | 6 +- src/sage/groups/affine_gps/euclidean_group.py | 4 +- .../matrix_gps/finitely_generated_gap.py | 4 +- src/sage/groups/matrix_gps/isometries.py | 6 +- src/sage/groups/matrix_gps/orthogonal.py | 8 +- src/sage/groups/matrix_gps/unitary.py | 4 +- src/sage/groups/perm_gps/permgroup.py | 4 +- src/sage/groups/perm_gps/permgroup_named.py | 24 ++-- src/sage/interacts/library.py | 96 ++++++++-------- src/sage/libs/coxeter3/coxeter_group.py | 2 +- src/sage/libs/eclib/interface.py | 8 +- .../differentiable/examples/euclidean.py | 2 +- src/sage/matrix/benchmark.py | 104 +++++++++--------- .../matrix/matrix_integer_dense_saturation.py | 4 +- src/sage/matrix/special.py | 80 +++++++------- .../numerical/backends/logging_backend.py | 2 +- .../numerical/interactive_simplex_method.py | 4 +- src/sage/numerical/optimize.py | 62 +++++------ src/sage/repl/configuration.py | 2 +- .../drinfeld_modules/drinfeld_module.py | 6 +- src/sage/sat/boolean_polynomials.py | 2 +- src/sage/sat/solvers/dimacs.py | 12 +- src/sage/sat/solvers/sat_lp.py | 6 +- src/sage/tensor/modules/comp.py | 2 +- .../modules/free_module_linear_group.py | 4 +- src/sage/tensor/modules/free_module_tensor.py | 2 +- src/tox.ini | 2 +- 45 files changed, 407 insertions(+), 407 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index b3079a7c4ee..be90c535c32 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -27,7 +27,7 @@ "python.linting.enabled": true, // The following pycodestyle arguments are the same as the pycodestyle-minimal // tox environnment, see the file SAGE_ROOT/src/tox.ini - "python.linting.pycodestyleArgs": ["--select= E111,E21,E222,E227,E25,E271,E303,E305,E306,E401,E502,E701,E702,E703,E71,E72,W291,W293,W391,W605"], + "python.linting.pycodestyleArgs": ["--select= E111,E21,E222,E225,E227,E228,E25,E271,E303,E305,E306,E401,E502,E701,E702,E703,E71,E72,W291,W293,W391,W605"], "cSpell.words": [ "furo", "Conda", diff --git a/src/sage/databases/cremona.py b/src/sage/databases/cremona.py index 54e83d639ad..a74eeac74d2 100644 --- a/src/sage/databases/cremona.py +++ b/src/sage/databases/cremona.py @@ -120,7 +120,7 @@ def build(name, data_tgz, largest_conductor=0, mini=False, decompress=True): raise RuntimeError('Please (re)move %s before building ' % db_path + 'database') if not os.path.exists(data_tgz): - raise IOError("The data file is not at %s"%data_tgz) + raise IOError("The data file is not at %s" % data_tgz) t = walltime() if decompress: @@ -246,7 +246,7 @@ def cremona_letter_code(n): return "a" s = "" while n != 0: - s = chr(n%26+97) + s + s = chr(n % 26+97) + s n //= 26 return s @@ -287,7 +287,7 @@ def old_cremona_letter_code(n): 'CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC' """ n -= 1 - k = n%26 + 65 + k = n % 26 + 65 label = chr(k)*int(n//26 + 1) return label @@ -678,7 +678,7 @@ def __init__(self, name, read_only=True, build=False): return SQLDatabase.__init__(self, db_path, read_only=read_only) if self.get_skeleton() != self._expected_skeleton: - raise RuntimeError('Database at %s does '%(self.__dblocation__) + raise RuntimeError('Database at %s does ' % (self.__dblocation__) + 'not appear to be a valid SQL Cremona database.') def __iter__(self): diff --git a/src/sage/databases/db_class_polynomials.py b/src/sage/databases/db_class_polynomials.py index ef6631c636b..642865a5d63 100644 --- a/src/sage/databases/db_class_polynomials.py +++ b/src/sage/databases/db_class_polynomials.py @@ -33,7 +33,7 @@ def _dbpath(self, disc, level=1): NotImplementedError: Level (= 2) > 1 not yet implemented """ if level != 1: - raise NotImplementedError("Level (= %s) > 1 not yet implemented"%level) + raise NotImplementedError("Level (= %s) > 1 not yet implemented" % level) n1 = 5000*((abs(disc)-1)//5000) s1 = disc_format % (n1+1) #_pad_int(n1+1, disc_length) s2 = disc_format % (n1+5000) diff --git a/src/sage/databases/knotinfo_db.py b/src/sage/databases/knotinfo_db.py index 2dba694604d..2828c3ace45 100644 --- a/src/sage/databases/knotinfo_db.py +++ b/src/sage/databases/knotinfo_db.py @@ -202,9 +202,9 @@ def excel(self): 'knotinfo_data_complete.xls' """ if self == KnotInfoFilename.knots: - return '%s.xls' %(self.value[1]) + return '%s.xls' % (self.value[1]) else: - return '%s.xlsx' %(self.value[1]) + return '%s.xlsx' % (self.value[1]) def csv(self): r""" @@ -218,7 +218,7 @@ def csv(self): sage: ki_db.filename.knots.csv() 'knotinfo_data_complete.csv' """ - return '%s.csv' %(self.value[1]) + return '%s.csv' % (self.value[1]) def num_knots(self, version): r""" @@ -232,7 +232,7 @@ def num_knots(self, version): sage: ki_db.filename.knots.num_knots('21.7') 'num_knots_21.7.sobj' """ - return 'num_knots_%s.sobj' %version + return 'num_knots_%s.sobj' % version def sobj_row(self): r""" @@ -275,9 +275,9 @@ def sobj_data(self, column): 'knotinfo_braid_notation' """ if column.column_type() == column.types.OnlyLinks: - return 'linkinfo_%s' %(column.name) + return 'linkinfo_%s' % (column.name) else: - return 'knotinfo_%s' %(column.name) + return 'knotinfo_%s' % (column.name) def description_url(self, column): r""" @@ -290,7 +290,7 @@ def description_url(self, column): sage: ki_db.filename.knots.description_url(ki_db.columns().braid_notation) 'https://knotinfo.math.indiana.edu/descriptions/braid_notation.html' """ - return '%sdescriptions/%s.html' %(self.url(), column.name) + return '%sdescriptions/%s.html' % (self.url(), column.name) def diagram_url(self, fname, single=False): r""" @@ -306,9 +306,9 @@ def diagram_url(self, fname, single=False): 'https://knotinfo.math.indiana.edu/diagrams/3_1' """ if single: - return '%sdiagrams/%s' %(self.url(), fname) + return '%sdiagrams/%s' % (self.url(), fname) else: - return '%sdiagram_display.php?%s' %(self.url(), fname) + return '%sdiagram_display.php?%s' % (self.url(), fname) knots = ['https://knotinfo.math.indiana.edu/', 'knotinfo_data_complete'] links = ['https://linkinfo.sitehost.iu.edu/', 'linkinfo_data_complete'] @@ -457,7 +457,7 @@ def demo_version(self): self._demo = False else: self._demo = True - self._num_knots = len([v for v in row_demo_sample.values() if v[1]==1]) + self._num_knots = len([v for v in row_demo_sample.values() if v[1] == 1]) return self._demo def knot_list(self): @@ -548,7 +548,7 @@ def _create_col_dict_sobj(self, sobj_path=None): col_type = KnotInfoColumnTypes.OnlyLinks column_dict[col] = [name, col_type] - save(column_dict, '%s/%s' %(sobj_path, self.filename.knots.sobj_column())) + save(column_dict, '%s/%s' % (sobj_path, self.filename.knots.sobj_column())) def _create_data_sobj(self, sobj_path=None): r""" @@ -582,7 +582,7 @@ def _create_data_sobj(self, sobj_path=None): # ---------------------------------------------------------------- # Columns that exist for knots and links # ---------------------------------------------------------------- - column_dict = load('%s/%s' %(sobj_path, self.filename.knots.sobj_column())) + column_dict = load('%s/%s' % (sobj_path, self.filename.knots.sobj_column())) cols = KnotInfoColumns('ColsTemp', column_dict) for col in cols: val_list = [] @@ -608,9 +608,9 @@ def _create_data_sobj(self, sobj_path=None): val_list.append(link_list[i][col.name]) if val_list: - save(val_list, '%s/%s' %(sobj_path, self.filename.knots.sobj_data(col))) + save(val_list, '%s/%s' % (sobj_path, self.filename.knots.sobj_data(col))) - save(row_dict, '%s/%s' %(sobj_path, self.filename.knots.sobj_row())) + save(row_dict, '%s/%s' % (sobj_path, self.filename.knots.sobj_row())) @cached_method def columns(self): @@ -652,7 +652,7 @@ def read_column_dict(self): return column_demo_sample sobj_path = self._sobj_path filename = self.filename.knots.sobj_column() - return load('%s/%s' %(sobj_path, filename)) + return load('%s/%s' % (sobj_path, filename)) # ------------------------------------------------------------------------------------------------------------- # read the dictionary for the row names that is the knot and link names from sobj-file @@ -680,7 +680,7 @@ def read_row_dict(self): return row_demo_sample sobj_path = self._sobj_path filename = self.filename.knots.sobj_row() - return load('%s/%s' %(sobj_path, filename)) + return load('%s/%s' % (sobj_path, filename)) # ------------------------------------------------------------------------------------------------------------- # return a dictionary to obtain the original name to a row_dict key @@ -752,7 +752,7 @@ def read(self, column): sage: ki_db = KnotInfoDataBase() """ if not isinstance(column, KnotInfoColumns): - raise TypeError('column must be an instance of enum %s' %(KnotInfoColumns)) + raise TypeError('column must be an instance of enum %s' % (KnotInfoColumns)) if self.demo_version(): return data_demo_sample[column] @@ -763,8 +763,8 @@ def read(self, column): else: filename = self.filename.knots.sobj_data(column) - verbose('loading data library %s ...' %(filename)) - res = load('%s/%s' %(sobj_path, filename)) + verbose('loading data library %s ...' % (filename)) + res = load('%s/%s' % (sobj_path, filename)) verbose('... finished!') return res diff --git a/src/sage/databases/sql_db.py b/src/sage/databases/sql_db.py index 4c5d439eda0..469fe454afb 100644 --- a/src/sage/databases/sql_db.py +++ b/src/sage/databases/sql_db.py @@ -147,7 +147,7 @@ def verify_type(type): """ types = ['INTEGER','INT','BOOLEAN','REAL','TEXT','BOOL','BLOB','NOTYPE'] if type.upper() not in types: - raise TypeError('%s is not a legal type.'%type) + raise TypeError('%s is not a legal type.' % type) return True @@ -215,7 +215,7 @@ def verify_operator(operator): binaries = ['=','<=','>=','like','<','>','<>','regexp'] unaries = ['is null','is not null'] if operator not in binaries and operator not in unaries: - raise TypeError('%s is not a legal operator.'%operator) + raise TypeError('%s is not a legal operator.' % operator) return True @@ -260,8 +260,8 @@ def construct_skeleton(database): else: typ = col[2] skeleton[table[0]][col[1]] = {'sql':typ, - 'primary_key':(col[5]!=0), 'index':(col[5]!=0), 'unique': False} - exe2 = cur.execute("PRAGMA index_list(%s)"%table[0]) + 'primary_key':(col[5] != 0), 'index':(col[5] != 0), 'unique': False} + exe2 = cur.execute("PRAGMA index_list(%s)" % table[0]) for col in exe2.fetchall(): if col[1].find('sqlite') == -1: if database.__dblocation__ == \ @@ -272,7 +272,7 @@ def construct_skeleton(database): skeleton[table[0]][name]['index'] = True skeleton[table[0]][name]['unique'] = bool(col[2]) else: - name = cur.execute("PRAGMA index_info(%s)"%col[1]) + name = cur.execute("PRAGMA index_info(%s)" % col[1]) name = name.fetchone()[2] skeleton[table[0]][name]['unique'] = bool(col[2]) return skeleton @@ -358,10 +358,10 @@ def row_str(row, html): for index in range(len(col_titles)): if index in pcol_index: if html: - plot = pcol_map[p%len(pcol_map)](row[index]) - plot.save('%d.png'%p, figsize=[1,1]) + plot = pcol_map[p % len(pcol_map)](row[index]) + plot.save('%d.png' % p, figsize=[1,1]) field_val = ' ' \ - + '%s
'%(row[index],p) \ + + '%s
' % (row[index],p) \ + '\n' p += 1 else: @@ -454,7 +454,7 @@ def __init__(self, database, *args, **kwds): """ if not isinstance(database, SQLDatabase): - raise TypeError('%s is not a valid SQLDatabase'%database) + raise TypeError('%s is not a valid SQLDatabase' % database) self.__database__ = database total_args = len(args) + len(kwds) if total_args == 0: @@ -496,7 +496,7 @@ def __init__(self, database, *args, **kwds): if query_dict['display_cols'] is not None: for column in query_dict['display_cols']: if column not in skel[table_name]: - raise ValueError("Table has no column %s"%column) + raise ValueError("Table has no column %s" % column) if query_dict['expression'][0] not in skel[table_name]: raise ValueError("Table has no column %s" % query_dict['expression'][0]) @@ -505,17 +505,17 @@ def __init__(self, database, *args, **kwds): self.__param_tuple__ = (str(query_dict['expression'][2]),) verify_operator(query_dict['expression'][1]) if query_dict['display_cols'] is None: - self.__query_string__ = 'SELECT , FROM %s WHERE '%table_name \ - + '%s.%s '%(table_name, query_dict['expression'][0]) \ - + '%s ?'%query_dict['expression'][1] + self.__query_string__ = 'SELECT , FROM %s WHERE ' % table_name \ + + '%s.%s ' % (table_name, query_dict['expression'][0]) \ + + '%s ?' % query_dict['expression'][1] else: - query_dict['display_cols'] = ['%s.%s'%(table_name, x) + query_dict['display_cols'] = ['%s.%s' % (table_name, x) for x in query_dict['display_cols']] self.__query_string__ = 'SELECT ' \ + ', '.join(query_dict['display_cols']) + ' FROM ' \ - + '%s WHERE %s.'%(table_name, table_name) \ - + '%s '%query_dict['expression'][0] \ - + '%s ?'%query_dict['expression'][1] + + '%s WHERE %s.' % (table_name, table_name) \ + + '%s ' % query_dict['expression'][0] \ + + '%s ?' % query_dict['expression'][1] else: self.__query_dict__ = {} self.__param_tuple__ = tuple() @@ -542,10 +542,10 @@ def __repr__(self): Query string: SELECT graph6 FROM graph_data WHERE num_vertices<=3 """ if not self.__query_string__: - return 'Empty query on %s.'%self.__database__.__dblocation__ - return "Query for sql database: %s"%self.__database__.__dblocation__ \ - + "\nQuery string: %s"%self.__query_string__ \ - + ("\nParameter tuple: %s"%str(self.__param_tuple__) if + return 'Empty query on %s.' % self.__database__.__dblocation__ + return "Query for sql database: %s" % self.__database__.__dblocation__ \ + + "\nQuery string: %s" % self.__query_string__ \ + + ("\nParameter tuple: %s" % str(self.__param_tuple__) if self.__param_tuple__ else "") def get_query_string(self): @@ -756,7 +756,7 @@ def intersect(self, other, join_table=None, join_dict=None, raise RuntimeError('Queries must be constructed using a ' + 'dictionary in order to be intersected.') if self.__database__ != other.__database__: - raise TypeError('Queries %s and %s must be '%(self, other) + raise TypeError('Queries %s and %s must be ' % (self, other) + 'attached to the same database.') if in_place: @@ -816,16 +816,16 @@ def _merge_queries(self, other, ret, join_table, join_dict, operator): if join_dict is not None: joins = join_table for table in join_dict: - joins += ' INNER JOIN %s ON %s.'%(table, join_table) \ - + '%s=%s.'%(join_dict[table][0], table) \ - + '%s '%join_dict[table][1] + joins += ' INNER JOIN %s ON %s.' % (table, join_table) \ + + '%s=%s.' % (join_dict[table][0], table) \ + + '%s ' % join_dict[table][1] ret.__query_string__ = re.sub(' FROM .* WHERE ', ' FROM ' + joins + 'WHERE ', self.__query_string__) # concatenate display cols disp1 = ret.__query_string__.split(' FROM') disp2 = other.__query_string__.split(' FROM') - disp1.insert(1, ',%s FROM'%disp2[0].split('SELECT ')[1]) + disp1.insert(1, ',%s FROM' % disp2[0].split('SELECT ')[1]) new_query = ''.join(disp1) # concatenate where clause @@ -880,7 +880,7 @@ def union(self, other, join_table=None, join_dict=None, in_place=False): raise RuntimeError('Queries must be constructed using a ' + 'dictionary in order to be unioned.') if self.__database__ != other.__database__: - raise TypeError('Queries %s and %s must be '%(self, other) + raise TypeError('Queries %s and %s must be ' % (self, other) + 'attached to the same database.') if in_place: @@ -1179,7 +1179,7 @@ def __copy__(self): new_loc = tmp_filename() + '.db' if not self.__read_only__: self.commit() - os.system('cp '+ self.__dblocation__ + ' ' + new_loc) + os.system('cp ' + self.__dblocation__ + ' ' + new_loc) D = SQLDatabase(filename=new_loc, read_only=False) return D @@ -1471,8 +1471,8 @@ def create_table(self, table_name, table_skeleton): else: statement.append(col + ' ' + typ) if table_skeleton[col]['index']: - index_statement += 'CREATE INDEX i_%s_%s'%(table_name, - col) + ' ON %s(%s);\n'%(table_name, col) + index_statement += 'CREATE INDEX i_%s_%s' % (table_name, + col) + ' ON %s(%s);\n' % (table_name, col) create_statement += ', '.join(statement) + ') ' self.__connection__.execute(create_statement) @@ -1544,9 +1544,9 @@ def add_column(self, table_name, col_name, col_dict, default='NULL'): if col_name.upper() in sqlite_keywords: raise ValueError("Column names cannot be SQLite keywords.") if table_name not in self.__skeleton__: - raise ValueError("Database has no table %s."%table_name) + raise ValueError("Database has no table %s." % table_name) if col_name in self.__skeleton__[table_name]: - raise ValueError("Table %s already has column %s."%(table_name,col_name)) + raise ValueError("Table %s already has column %s." % (table_name,col_name)) # Update the skeleton: self.__skeleton__[table_name][col_name] = verify_column(col_dict) @@ -1710,9 +1710,9 @@ def drop_column(self, table_name, col_name): raise RuntimeError('Cannot drop columns in a read only database.') # Check input: if table_name not in self.__skeleton__: - raise ValueError("Database has no table %s."%table_name) + raise ValueError("Database has no table %s." % table_name) if col_name not in self.__skeleton__[table_name]: - raise ValueError("Table %s has no column %s."%(table_name,col_name)) + raise ValueError("Table %s has no column %s." % (table_name,col_name)) # Update the skeleton: self.__skeleton__[table_name].pop(col_name) @@ -1744,11 +1744,11 @@ def rename_table(self, table_name, new_name): raise RuntimeError('Cannot rename tables in a read only database.') # Check input: if table_name not in self.__skeleton__: - raise ValueError('Database has no table %s.'%table_name) + raise ValueError('Database has no table %s.' % table_name) if new_name in self.__skeleton__: - raise ValueError('Database already has table %s.'%new_name) + raise ValueError('Database already has table %s.' % new_name) - self.__connection__.execute('ALTER TABLE %s RENAME TO '%table_name + self.__connection__.execute('ALTER TABLE %s RENAME TO ' % table_name + new_name) # Update skeleton: @@ -1777,7 +1777,7 @@ def drop_table(self, table_name): raise RuntimeError('Cannot drop tables from a read only ' + 'database.') if table_name not in self.__skeleton__: - raise ValueError("Database has no table %s."%table_name) + raise ValueError("Database has no table %s." % table_name) self.__connection__.execute('DROP TABLE ' + table_name) @@ -1805,7 +1805,7 @@ def drop_data_from_table(self, table_name): if self.__read_only__: raise RuntimeError('Cannot remove data from a read only database.') if table_name not in self.__skeleton__: - raise ValueError("Database has no table %s."%table_name) + raise ValueError("Database has no table %s." % table_name) self.__connection__.execute('DELETE FROM ' + table_name) def make_index(self, col_name, table_name, unique=False): @@ -1838,9 +1838,9 @@ def make_index(self, col_name, table_name, unique=False): if self.__read_only__: raise RuntimeError('Cannot modify a read only database.') if table_name not in self.__skeleton__: - raise ValueError("Database has no table %s."%table_name) + raise ValueError("Database has no table %s." % table_name) if col_name not in self.__skeleton__[table_name]: - raise ValueError("Table %s has no column %s."%(table_name,col_name)) + raise ValueError("Table %s has no column %s." % (table_name,col_name)) if unique: index_string = 'CREATE UNIQUE INDEX ' + col_name + ' ON ' \ @@ -1921,9 +1921,9 @@ def make_unique(self, table_name, col_name): if self.__read_only__: raise RuntimeError('Cannot modify a read only database') if table_name not in self.__skeleton__: - raise ValueError("Database has no table %s."%table_name) + raise ValueError("Database has no table %s." % table_name) if col_name not in self.__skeleton__[table_name]: - raise ValueError("Table %s has no column %s."%(table_name, col_name)) + raise ValueError("Table %s has no column %s." % (table_name, col_name)) # Update the skeleton: self.__skeleton__[table_name][col_name]['unique'] = True @@ -1959,9 +1959,9 @@ def drop_unique(self, table_name, col_name): if self.__read_only__: raise RuntimeError('Cannot modify a read only database.') if table_name not in self.__skeleton__: - raise ValueError("Database has no table %s."%table_name) + raise ValueError("Database has no table %s." % table_name) if col_name not in self.__skeleton__[table_name]: - raise ValueError("Table %s has no column %s."%(table_name, col_name)) + raise ValueError("Table %s has no column %s." % (table_name, col_name)) if self.__skeleton__[table_name][col_name]['primary_key']: raise ValueError("Primary keys must be unique.") @@ -2002,9 +2002,9 @@ def make_primary_key(self, table_name, col_name): if self.__read_only__: raise RuntimeError('Cannot modify a read only database.') if table_name not in self.__skeleton__: - raise ValueError("Database has no table %s."%table_name) + raise ValueError("Database has no table %s." % table_name) if col_name not in self.__skeleton__[table_name]: - raise ValueError("Table %s has no column %s."%(table_name, col_name)) + raise ValueError("Table %s has no column %s." % (table_name, col_name)) # Update the skeleton: self.__skeleton__[table_name][col_name]['primary_key'] = True @@ -2046,9 +2046,9 @@ def drop_primary_key(self, table_name, col_name): if self.__read_only__: raise RuntimeError('Cannot modify a read only database.') if table_name not in self.__skeleton__: - raise ValueError("Database has no table %s."%table_name) + raise ValueError("Database has no table %s." % table_name) if col_name not in self.__skeleton__[table_name]: - raise ValueError("Table %s has no column %s."%(table_name,col_name)) + raise ValueError("Table %s has no column %s." % (table_name,col_name)) if not self.__skeleton__[table_name][col_name]['primary_key']: return # silently diff --git a/src/sage/doctest/control.py b/src/sage/doctest/control.py index 11bf91a3aef..4a4e8a44737 100644 --- a/src/sage/doctest/control.py +++ b/src/sage/doctest/control.py @@ -749,7 +749,7 @@ def load_stats(self, filename): with open(filename) as stats_file: self.stats.update(json.load(stats_file)) except Exception: - self.log("Error loading stats from %s"%filename) + self.log("Error loading stats from %s" % filename) def save_stats(self, filename): """ @@ -838,7 +838,7 @@ def create_run_id(self): Running doctests with ID ... """ self.run_id = time.strftime('%Y-%m-%d-%H-%M-%S-') + "%08x" % random.getrandbits(32) - self.log("Running doctests with ID %s."%self.run_id) + self.log("Running doctests with ID %s." % self.run_id) def add_files(self): r""" @@ -1128,16 +1128,16 @@ def run_doctests(self): if self.sources: filestr = ", ".join(([count_noun(nfiles, "file")] if nfiles else []) + ([count_noun(nother, "other source")] if nother else [])) - threads = " using %s threads"%(self.options.nthreads) if self.options.nthreads > 1 else "" + threads = " using %s threads" % (self.options.nthreads) if self.options.nthreads > 1 else "" iterations = [] if self.options.global_iterations > 1: - iterations.append("%s global iterations"%(self.options.global_iterations)) + iterations.append("%s global iterations" % (self.options.global_iterations)) if self.options.file_iterations > 1: - iterations.append("%s file iterations"%(self.options.file_iterations)) + iterations.append("%s file iterations" % (self.options.file_iterations)) iterations = ", ".join(iterations) if iterations: - iterations = " (%s)"%(iterations) - self.log("Doctesting %s%s%s."%(filestr, threads, iterations)) + iterations = " (%s)" % (iterations) + self.log("Doctesting %s%s%s." % (filestr, threads, iterations)) self.reporter = DocTestReporter(self) self.dispatcher = DocTestDispatcher(self) N = self.options.global_iterations @@ -1246,10 +1246,10 @@ def _assemble_cmd(self): raise ValueError("You cannot run gdb/lldb/valgrind on the whole sage library") for o in ("all", "long", "force_lib", "verbose", "failed", "new"): if o in opt: - cmd += "--%s "%o + cmd += "--%s " % o for o in ("timeout", "randorder", "stats_path"): if o in opt: - cmd += "--%s=%s "%(o, opt[o]) + cmd += "--%s=%s " % (o, opt[o]) if "optional" in opt: cmd += "--optional={} ".format(self._optional_tags_string()) return cmd + " ".join(self.files) @@ -1315,9 +1315,9 @@ def run_val_gdb(self, testing=False): flags = os.getenv("SAGE_MEMCHECK_FLAGS") if flags is None: flags = "--leak-resolution=high --leak-check=full --num-callers=25 " - flags += '''--suppressions="%s" '''%(os.path.join(SAGE_EXTCODE,"valgrind","pyalloc.supp")) - flags += '''--suppressions="%s" '''%(os.path.join(SAGE_EXTCODE,"valgrind","sage.supp")) - flags += '''--suppressions="%s" '''%(os.path.join(SAGE_EXTCODE,"valgrind","sage-additional.supp")) + flags += '''--suppressions="%s" ''' % (os.path.join(SAGE_EXTCODE,"valgrind","pyalloc.supp")) + flags += '''--suppressions="%s" ''' % (os.path.join(SAGE_EXTCODE,"valgrind","sage.supp")) + flags += '''--suppressions="%s" ''' % (os.path.join(SAGE_EXTCODE,"valgrind","sage-additional.supp")) elif opt.massif: toolname = "massif" flags = os.getenv("SAGE_MASSIF_FLAGS", "--depth=6 ") @@ -1327,7 +1327,7 @@ def run_val_gdb(self, testing=False): elif opt.omega: toolname = "exp-omega" flags = os.getenv("SAGE_OMEGA_FLAGS", "") - cmd = "exec valgrind --tool=%s "%(toolname) + cmd = "exec valgrind --tool=%s " % (toolname) flags += f''' --log-file={shlex.quote(logfile)} ''' if opt.omega: toolname = "omega" @@ -1623,7 +1623,7 @@ def stringify(x): # Declaration of doctest strings ############################################################################### -test_hide=r"""r{quotmark} +test_hide = r"""r{quotmark} {prompt}: next(graphs.fullerenes(20)) Traceback (most recent call last): ... diff --git a/src/sage/doctest/parsing.py b/src/sage/doctest/parsing.py index 3a2ac1b98d4..5c37ea1422b 100644 --- a/src/sage/doctest/parsing.py +++ b/src/sage/doctest/parsing.py @@ -233,7 +233,7 @@ def parse_optional_tags(string, *, return_string_sans_tags=False): if return_string_sans_tags: is_persistent = tags and first_line_sans_comments.strip() == 'sage:' and not rest # persistent (block-scoped) tag - return tags, (first_line + '\n' + rest%literals if rest is not None + return tags, (first_line + '\n' + rest % literals if rest is not None else first_line), is_persistent else: return tags diff --git a/src/sage/doctest/reporting.py b/src/sage/doctest/reporting.py index 361fea344c2..fba7bb6e449 100644 --- a/src/sage/doctest/reporting.py +++ b/src/sage/doctest/reporting.py @@ -88,7 +88,7 @@ def signal_name(sig): return "terminate" if sig == SIGBUS: return "bus error" - return "signal %s"%sig + return "signal %s" % sig class DocTestReporter(SageObject): """ @@ -422,26 +422,26 @@ def report(self, source, timeout, return_code, results, output, pid=None): elif sig == SIGKILL: fail_msg += " (and interrupt failed)" else: - fail_msg += " (with %s after interrupt)"%signal_name(sig) + fail_msg += " (with %s after interrupt)" % signal_name(sig) if the_baseline_stats.get('failed', False): fail_msg += " [failed in baseline]" - log(" %s\n%s\nTests run before %s timed out:"%(fail_msg, "*"*70, process_name)) + log(" %s\n%s\nTests run before %s timed out:" % (fail_msg, "*"*70, process_name)) log(output) log("*"*70) - postscript['lines'].append(cmd + " # %s"%fail_msg) + postscript['lines'].append(cmd + " # %s" % fail_msg) stats[basename] = dict(failed=True, walltime=1e6, ntests=ntests) if not the_baseline_stats.get('failed', False): self.error_status |= 4 elif return_code: if return_code > 0: - fail_msg = "Bad exit: %s"%return_code + fail_msg = "Bad exit: %s" % return_code else: - fail_msg = "Killed due to %s"%signal_name(-return_code) + fail_msg = "Killed due to %s" % signal_name(-return_code) if ntests > 0: fail_msg += " after testing finished" if the_baseline_stats.get('failed', False): fail_msg += " [failed in baseline]" - log(" %s\n%s\nTests run before %s failed:"%(fail_msg,"*"*70, process_name)) + log(" %s\n%s\nTests run before %s failed:" % (fail_msg,"*"*70, process_name)) log(output) log("*"*70) postscript['lines'].append(cmd + " # %s" % fail_msg) @@ -458,13 +458,13 @@ def report(self, source, timeout, return_code, results, output, pid=None): else: cpu = 1e6 if result_dict.err == 'badresult': - log(" Error in doctesting framework (bad result returned)\n%s\nTests run before error:"%("*"*70)) + log(" Error in doctesting framework (bad result returned)\n%s\nTests run before error:" % ("*"*70)) log(output) log("*"*70) postscript['lines'].append(cmd + " # Testing error: bad result") self.error_status |= 64 elif result_dict.err == 'noresult': - log(" Error in doctesting framework (no result returned)\n%s\nTests run before error:"%("*"*70)) + log(" Error in doctesting framework (no result returned)\n%s\nTests run before error:" % ("*"*70)) log(output) log("*"*70) postscript['lines'].append(cmd + " # Testing error: no result") @@ -475,7 +475,7 @@ def report(self, source, timeout, return_code, results, output, pid=None): tabs = " " + ",".join(result_dict.tab_linenos) if len(result_dict.tab_linenos) > 1: tabs = "s" + tabs - log(" Error: TAB character found at line%s"%(tabs)) + log(" Error: TAB character found at line%s" % (tabs)) postscript['lines'].append(cmd + " # Tab character found") self.error_status |= 32 elif result_dict.err == 'line_number': @@ -491,13 +491,13 @@ def report(self, source, timeout, return_code, results, output, pid=None): err = result_dict.err.__name__ else: err = repr(result_dict.err) - fail_msg = "%s in doctesting framework"%err + fail_msg = "%s in doctesting framework" % err - log(" %s\n%s"%(fail_msg, "*"*70)) + log(" %s\n%s" % (fail_msg, "*"*70)) if output: log("Tests run before doctest exception:\n" + output) log("*"*70) - postscript['lines'].append(cmd + " # %s"%fail_msg) + postscript['lines'].append(cmd + " # %s" % fail_msg) if hasattr(result_dict, 'tb'): log(result_dict.tb) if hasattr(result_dict, 'walltime'): @@ -530,28 +530,28 @@ def report(self, source, timeout, return_code, results, output, pid=None): if tag == "long time": if not self.controller.options.long: if self.controller.options.show_skipped: - log(" %s not run"%(count_noun(nskipped, "long test"))) + log(" %s not run" % (count_noun(nskipped, "long test"))) elif tag == "not tested": if self.controller.options.show_skipped: - log(" %s not run"%(count_noun(nskipped, "not tested test"))) + log(" %s not run" % (count_noun(nskipped, "not tested test"))) elif tag == "not implemented": if self.controller.options.show_skipped: - log(" %s for not implemented functionality not run"%(count_noun(nskipped, "test"))) + log(" %s for not implemented functionality not run" % (count_noun(nskipped, "test"))) else: if not self.were_doctests_with_optional_tag_run(tag): if tag == "bug": if self.controller.options.show_skipped: - log(" %s not run due to known bugs"%(count_noun(nskipped, "test"))) + log(" %s not run due to known bugs" % (count_noun(nskipped, "test"))) elif tag == "": if self.controller.options.show_skipped: - log(" %s not run"%(count_noun(nskipped, "unlabeled test"))) + log(" %s not run" % (count_noun(nskipped, "unlabeled test"))) else: if self.controller.options.show_skipped: - log(" %s not run"%(count_noun(nskipped, tag + " test"))) + log(" %s not run" % (count_noun(nskipped, tag + " test"))) nskipped = result_dict.walltime_skips if self.controller.options.show_skipped: - log(" %s not run because we ran out of time"%(count_noun(nskipped, "test"))) + log(" %s not run because we ran out of time" % (count_noun(nskipped, "test"))) if nskipped != 0: # It would be nice to report "a/b tests run" instead of @@ -562,11 +562,11 @@ def report(self, source, timeout, return_code, results, output, pid=None): # tests multiple times, and some other unclear mangling # of these numbers that was not clear to the author. ntests_run = result_dict.tests - total = "%d%% of tests run"%(round(100*ntests_run/float(ntests_run + nskipped))) + total = "%d%% of tests run" % (round(100*ntests_run/float(ntests_run + nskipped))) else: total = count_noun(ntests, "test") if not (self.controller.options.only_errors and not f): - log(" [%s, %s%.2f s]" % (total, "%s, "%(count_noun(f, "failure")) if f else "", wall)) + log(" [%s, %s%.2f s]" % (total, "%s, " % (count_noun(f, "failure")) if f else "", wall)) self.sources_completed += 1 @@ -658,7 +658,7 @@ def finalize(self): log = self.controller.log postscript = self.postscript if self.sources_completed < len(self.controller.sources) * self.controller.options.global_iterations: - postscript['lines'].append("Doctests interrupted: %s/%s files tested"%(self.sources_completed, len(self.controller.sources))) + postscript['lines'].append("Doctests interrupted: %s/%s files tested" % (self.sources_completed, len(self.controller.sources))) self.error_status |= 128 elif not postscript['lines']: postscript['lines'].append("All tests passed!") diff --git a/src/sage/doctest/util.py b/src/sage/doctest/util.py index 7446373eae0..c7774a6472b 100644 --- a/src/sage/doctest/util.py +++ b/src/sage/doctest/util.py @@ -51,13 +51,13 @@ def count_noun(number, noun, plural=None, pad_number=False, pad_noun=False): else: pad_noun = "" if pad_number: - number_str = ("%%%sd"%pad_number)%number + number_str = ("%%%sd" % pad_number) % number else: - number_str = "%d"%number + number_str = "%d" % number if number == 1: - return "%s %s%s"%(number_str, noun, pad_noun) + return "%s %s%s" % (number_str, noun, pad_noun) else: - return "%s %s"%(number_str, plural) + return "%s %s" % (number_str, plural) def dict_difference(self, other): diff --git a/src/sage/functions/jacobi.py b/src/sage/functions/jacobi.py index 629b24ce930..063dc8c7b78 100644 --- a/src/sage/functions/jacobi.py +++ b/src/sage/functions/jacobi.py @@ -419,86 +419,86 @@ def _derivative_(self, x, m, diff_param): elif diff_param == 1: # From Maxima if self.kind == 'nd': - return (HALF*((x + elliptic_e(arcsin(jacobi_sn(x, m)), m)/ + return (HALF*((x + elliptic_e(arcsin(jacobi_sn(x, m)), m) / (m - Integer(1)))*jacobi_sn(x, m)*jacobi_cn(x, m) - - jacobi_dn(x, m)*jacobi_sn(x, m)**Integer(2)/(m - Integer(1)))/ + jacobi_dn(x, m)*jacobi_sn(x, m)**Integer(2)/(m - Integer(1))) / jacobi_dn(x, m)**Integer(2)) elif self.kind == 'ns': return (HALF*(jacobi_sn(x, m)*jacobi_cn(x, m)**Integer(2)/(m - Integer(1)) - - (x + elliptic_e(arcsin(jacobi_sn(x, m)), m)/ - (m - Integer(1)))*jacobi_dn(x, m)*jacobi_cn(x, m)/m)/ + (x + elliptic_e(arcsin(jacobi_sn(x, m)), m) / + (m - Integer(1)))*jacobi_dn(x, m)*jacobi_cn(x, m)/m) / jacobi_sn(x, m)**Integer(2)) elif self.kind == 'nc': return (-HALF*(jacobi_sn(x, m)**Integer(2)*jacobi_cn(x, m)/(m - Integer(1)) - - (x + elliptic_e(arcsin(jacobi_sn(x, m)), m)/ - (m - Integer(1)))*jacobi_dn(x, m)* + (x + elliptic_e(arcsin(jacobi_sn(x, m)), m) / + (m - Integer(1)))*jacobi_dn(x, m) * jacobi_sn(x, m)/m)/jacobi_cn(x, m)**Integer(2)) elif self.kind == 'dn': - return (-HALF*(x + elliptic_e(arcsin(jacobi_sn(x, m)), m)/ + return (-HALF*(x + elliptic_e(arcsin(jacobi_sn(x, m)), m) / (m - Integer(1)))*jacobi_sn(x, m)*jacobi_cn(x, m) + HALF*jacobi_dn(x, m)*jacobi_sn(x, m)**Integer(2)/(m - Integer(1))) elif self.kind == 'ds': return (HALF*(jacobi_sn(x, m)*jacobi_cn(x, m)**Integer(2)/(m - Integer(1)) - - (x + elliptic_e(arcsin(jacobi_sn(x, m)), m)/ - (m - Integer(1)))*jacobi_dn(x, m)*jacobi_cn(x, m)/m)* + (x + elliptic_e(arcsin(jacobi_sn(x, m)), m) / + (m - Integer(1)))*jacobi_dn(x, m)*jacobi_cn(x, m)/m) * jacobi_dn(x, m)/jacobi_sn(x, m)**Integer(2) - - HALF*((x + elliptic_e(arcsin(jacobi_sn(x, m)), m)/ + HALF*((x + elliptic_e(arcsin(jacobi_sn(x, m)), m) / (m - Integer(1)))*jacobi_sn(x, m)*jacobi_cn(x, m) - - jacobi_dn(x, m)*jacobi_sn(x, m)**Integer(2)/(m - Integer(1)))/ + jacobi_dn(x, m)*jacobi_sn(x, m)**Integer(2)/(m - Integer(1))) / jacobi_sn(x, m)) elif self.kind == 'dc': return (-HALF*(jacobi_sn(x, m)**Integer(2)*jacobi_cn(x, m)/(m - Integer(1)) - - (x + elliptic_e(arcsin(jacobi_sn(x, m)), m)/ - (m - Integer(1)))*jacobi_dn(x, m)* - jacobi_sn(x, m)/m)*jacobi_dn(x, m)/ + (x + elliptic_e(arcsin(jacobi_sn(x, m)), m) / + (m - Integer(1)))*jacobi_dn(x, m) * + jacobi_sn(x, m)/m)*jacobi_dn(x, m) / jacobi_cn(x, m)**Integer(2) - - HALF*((x + elliptic_e(arcsin(jacobi_sn(x, m)), m)/ + HALF*((x + elliptic_e(arcsin(jacobi_sn(x, m)), m) / (m - Integer(1)))*jacobi_sn(x, m)*jacobi_cn(x, m) - - jacobi_dn(x, m)*jacobi_sn(x, m)**Integer(2)/(m - Integer(1)))/ + jacobi_dn(x, m)*jacobi_sn(x, m)**Integer(2)/(m - Integer(1))) / jacobi_cn(x, m)) elif self.kind == 'sn': return (-HALF*jacobi_sn(x, m)*jacobi_cn(x, m)**Integer(2)/(m - Integer(1)) + - HALF*(x + elliptic_e(arcsin(jacobi_sn(x, m)), m)/ + HALF*(x + elliptic_e(arcsin(jacobi_sn(x, m)), m) / (m - Integer(1)))*jacobi_dn(x, m)*jacobi_cn(x, m)/m) elif self.kind == 'sd': return (-HALF*(jacobi_sn(x, m)*jacobi_cn(x, m)**Integer(2)/(m - Integer(1)) - - (x + elliptic_e(arcsin(jacobi_sn(x, m)), m)/ - (m - Integer(1)))*jacobi_dn(x, m)*jacobi_cn(x, m)/m)/ - jacobi_dn(x, m) + HALF* - ((x + elliptic_e(arcsin(jacobi_sn(x, m)), m)/ + (x + elliptic_e(arcsin(jacobi_sn(x, m)), m) / + (m - Integer(1)))*jacobi_dn(x, m)*jacobi_cn(x, m)/m) / + jacobi_dn(x, m) + HALF * + ((x + elliptic_e(arcsin(jacobi_sn(x, m)), m) / (m - Integer(1)))*jacobi_sn(x, m)*jacobi_cn(x, m) - - jacobi_dn(x, m)*jacobi_sn(x, m)**Integer(2)/(m - Integer(1)))* + jacobi_dn(x, m)*jacobi_sn(x, m)**Integer(2)/(m - Integer(1))) * jacobi_sn(x, m)/jacobi_dn(x, m)**Integer(2)) elif self.kind == 'sc': return (-HALF*(jacobi_sn(x, m)*jacobi_cn(x, m)**Integer(2)/(m - Integer(1)) - - (x + elliptic_e(arcsin(jacobi_sn(x, m)), m)/ - (m - Integer(1)))*jacobi_dn(x, m)* + (x + elliptic_e(arcsin(jacobi_sn(x, m)), m) / + (m - Integer(1)))*jacobi_dn(x, m) * jacobi_cn(x, m)/m)/jacobi_cn(x, m) - HALF*(jacobi_sn(x, m)**Integer(2)*jacobi_cn(x, m)/(m - Integer(1)) - - (x + elliptic_e(arcsin(jacobi_sn(x, m)), m)/ - (m - Integer(1)))*jacobi_dn(x, m)*jacobi_sn(x, m)/m)* + (x + elliptic_e(arcsin(jacobi_sn(x, m)), m) / + (m - Integer(1)))*jacobi_dn(x, m)*jacobi_sn(x, m)/m) * jacobi_sn(x, m)/jacobi_cn(x, m)**Integer(2)) elif self.kind == 'cn': return (HALF*jacobi_sn(x, m)**Integer(2)*jacobi_cn(x, m)/(m - Integer(1)) - - HALF*(x + elliptic_e(arcsin(jacobi_sn(x, m)), m)/ + HALF*(x + elliptic_e(arcsin(jacobi_sn(x, m)), m) / (m - Integer(1)))*jacobi_dn(x, m)*jacobi_sn(x, m)/m) elif self.kind == 'cd': return (HALF*(jacobi_sn(x, m)**Integer(2)*jacobi_cn(x, m)/(m - Integer(1)) - - (x + elliptic_e(arcsin(jacobi_sn(x, m)), m)/ - (m - Integer(1)))*jacobi_dn(x, m)*jacobi_sn(x, m)/m)/ + (x + elliptic_e(arcsin(jacobi_sn(x, m)), m) / + (m - Integer(1)))*jacobi_dn(x, m)*jacobi_sn(x, m)/m) / jacobi_dn(x, m) + - HALF*((x + elliptic_e(arcsin(jacobi_sn(x, m)), m)/ + HALF*((x + elliptic_e(arcsin(jacobi_sn(x, m)), m) / (m - Integer(1)))*jacobi_sn(x, m)*jacobi_cn(x, m) - - jacobi_dn(x, m)*jacobi_sn(x, m)**Integer(2)/(m - Integer(1)))* + jacobi_dn(x, m)*jacobi_sn(x, m)**Integer(2)/(m - Integer(1))) * jacobi_cn(x, m)/jacobi_dn(x, m)**Integer(2)) elif self.kind == 'cs': return (HALF*(jacobi_sn(x, m)*jacobi_cn(x, m)**Integer(2)/(m - Integer(1)) - - (x + elliptic_e(arcsin(jacobi_sn(x, m)), m)/ - (m - Integer(1)))*jacobi_dn(x, m)*jacobi_cn(x, m)/m)* + (x + elliptic_e(arcsin(jacobi_sn(x, m)), m) / + (m - Integer(1)))*jacobi_dn(x, m)*jacobi_cn(x, m)/m) * jacobi_cn(x, m)/jacobi_sn(x, m)**Integer(2) + HALF*(jacobi_sn(x, m)**Integer(2)*jacobi_cn(x, m)/(m - Integer(1)) - - (x + elliptic_e(arcsin(jacobi_sn(x, m)), m)/ - (m - Integer(1)))*jacobi_dn(x, m)*jacobi_sn(x, m)/m)/ + (x + elliptic_e(arcsin(jacobi_sn(x, m)), m) / + (m - Integer(1)))*jacobi_dn(x, m)*jacobi_sn(x, m)/m) / jacobi_sn(x, m)) def _latex_(self): diff --git a/src/sage/functions/other.py b/src/sage/functions/other.py index 9dbe9787545..249eb2ea56f 100644 --- a/src/sage/functions/other.py +++ b/src/sage/functions/other.py @@ -411,7 +411,7 @@ def _print_latex_(self, x): sage: latex(ceil(x)) # indirect doctest # needs sage.symbolic \left \lceil x \right \rceil """ - return r"\left \lceil %s \right \rceil"%latex(x) + return r"\left \lceil %s \right \rceil" % latex(x) #FIXME: this should be moved to _eval_ def __call__(self, x, **kwds): @@ -580,7 +580,7 @@ def _print_latex_(self, x): sage: latex(floor(x)) # needs sage.symbolic \left \lfloor x \right \rfloor """ - return r"\left \lfloor %s \right \rfloor"%latex(x) + return r"\left \lfloor %s \right \rfloor" % latex(x) #FIXME: this should be moved to _eval_ def __call__(self, x, **kwds): @@ -1114,7 +1114,7 @@ def _evalf_(self, x, parent=None, algorithm=None): return parent(x).arg() -arg=Function_arg() +arg = Function_arg() ############################ diff --git a/src/sage/functions/piecewise.py b/src/sage/functions/piecewise.py index ff3851a1776..a41c07228fc 100644 --- a/src/sage/functions/piecewise.py +++ b/src/sage/functions/piecewise.py @@ -719,7 +719,7 @@ def piecewise_add(self, parameters, variable, other): except ValueError: ex2 = 0 ex = ex1 + ex2 - if i>0 and funcs[-1] == ex: + if i > 0 and funcs[-1] == ex: # extend the previous domain rs += domain[-1] domain[-1] = rs @@ -927,7 +927,7 @@ def critical_points(self, parameters, variable): for interval in domain: a = interval.lower() b = interval.upper() - for root in maxima.allroots(SR(f).diff(x)==0): + for root in maxima.allroots(SR(f).diff(x) == 0): root = float(root.rhs()) if a < root < b: crit_pts.append(root) @@ -995,7 +995,7 @@ def convolution(self, parameters, variable, other): raise ValueError('one of the piecewise functions is nowhere defined') fd, f0 = parameters[0] gd, g0 = next(other.items()) - if len(f)==1 and len(g)==1: + if len(f) == 1 and len(g) == 1: f = f.unextend_zero() g = g.unextend_zero() a1 = fd[0].lower() @@ -1010,19 +1010,19 @@ def convolution(self, parameters, variable, other): fg2 = definite_integral(i1*i2, uu, tt-b2, tt-b1).subs({tt:variable}) fg3 = definite_integral(i1*i2, uu, tt-b2, a2).subs({tt:variable}) fg4 = definite_integral(i1*i2, uu, a1, a2).subs({tt:variable}) - if a1-b11 or len(g)>1: + if len(f) > 1 or len(g) > 1: z = piecewise([[(0,0),0]]) for fpiece in f.pieces(): for gpiece in g.pieces(): @@ -1126,14 +1126,14 @@ def laplace(self, parameters, variable, x='x', s='t'): x = SR.var(x) s = SR.var(s) - assume(s>0) + assume(s > 0) result = 0 for domain, f in parameters: for interval in domain: a = interval.lower() b = interval.upper() result += (SR(f)*exp(-s*x)).integral(x,a,b) - forget(s>0) + forget(s > 0) return result def fourier_series_cosine_coefficient(self, parameters, diff --git a/src/sage/graphs/generators/basic.py b/src/sage/graphs/generators/basic.py index 5dfe78f01a8..5dbacb4de26 100644 --- a/src/sage/graphs/generators/basic.py +++ b/src/sage/graphs/generators/basic.py @@ -435,9 +435,9 @@ def CorrelationGraph(seqs, alpha, include_anticorrelation): # compare against alpha to get adjacency matrix if include_anticorrelation: - boolean_adjacency_matrix = abs(corrs)>=alpha + boolean_adjacency_matrix = abs(corrs) >= alpha else: - boolean_adjacency_matrix = corrs>=alpha + boolean_adjacency_matrix = corrs >= alpha adjacency_matrix = Matrix(boolean_adjacency_matrix.astype(int)) diff --git a/src/sage/graphs/partial_cube.py b/src/sage/graphs/partial_cube.py index 70456e548c9..147f1acb097 100644 --- a/src/sage/graphs/partial_cube.py +++ b/src/sage/graphs/partial_cube.py @@ -329,7 +329,7 @@ def is_partial_cube(G, certificate=False): labeled = Graph([contracted.vertices(sort=False), []]) for v, w in contracted.edge_iterator(labels=False): diff = bitvec[v] ^ bitvec[w] - if not diff or not bitvec[w] &~ bitvec[v]: + if not diff or not bitvec[w] & ~bitvec[v]: continue # zero edge or wrong direction if diff not in neighbors: return fail diff --git a/src/sage/groups/abelian_gps/abelian_aut.py b/src/sage/groups/abelian_gps/abelian_aut.py index 86051c72b28..b27f9bdb220 100644 --- a/src/sage/groups/abelian_gps/abelian_aut.py +++ b/src/sage/groups/abelian_gps/abelian_aut.py @@ -298,7 +298,7 @@ def _element_constructor_(self, x, check=True): # Also conversions between the domains use the smith gens. if x.domain().invariants() != self.domain().gens_orders(): raise ValueError("invariants of domains must agree") - if not x.domain()==x.codomain(): + if not x.domain() == x.codomain(): raise ValueError("domain and codomain do not agree") if not x.kernel().invariants() == (): raise ValueError("not an automorphism") diff --git a/src/sage/groups/abelian_gps/abelian_group.py b/src/sage/groups/abelian_gps/abelian_group.py index 898ca9cebb5..121cf7524db 100644 --- a/src/sage/groups/abelian_gps/abelian_group.py +++ b/src/sage/groups/abelian_gps/abelian_group.py @@ -764,7 +764,7 @@ def elementary_divisors(self): """ from sage.matrix.constructor import diagonal_matrix ed = diagonal_matrix(ZZ, self.gens_orders()).elementary_divisors() - return tuple(d for d in ed if d!=1) + return tuple(d for d in ed if d != 1) @cached_method def exponent(self): @@ -823,7 +823,7 @@ def _group_notation(self, eldv): v = [] for x in eldv: if x: - v.append("C%s"%x) + v.append("C%s" % x) else: v.append("Z") return ' x '.join(v) @@ -893,12 +893,12 @@ def _gap_init_(self): 'AbelianPcpGroup([0, 3, 4])' """ if self.is_finite(): - return 'AbelianGroup(%s)'%list(self.gens_orders()) + return 'AbelianGroup(%s)' % list(self.gens_orders()) from sage.features.gap import GapPackage # Make sure to LoadPackage("Polycyclic") in gap GapPackage("polycyclic", spkg="gap_packages").require() - return 'AbelianPcpGroup(%s)'%list(self.gens_orders()) + return 'AbelianPcpGroup(%s)' % list(self.gens_orders()) def gen(self, i=0): """ @@ -920,7 +920,7 @@ def gen(self, i=0): """ n = self.ngens() if i < 0 or i >= n: - raise IndexError("Argument i (= %s) must be between 0 and %s."%(i, n-1)) + raise IndexError("Argument i (= %s) must be between 0 and %s." % (i, n-1)) x = [0]*n if self._gens_orders[i] != 1: x[i] = 1 @@ -1142,7 +1142,7 @@ def permutation_group(self): if not self.is_finite(): raise TypeError('Abelian group must be finite') from sage.groups.perm_gps.permgroup import PermutationGroup - s = 'Image(IsomorphismPermGroup(%s))'%self._gap_init_() + s = 'Image(IsomorphismPermGroup(%s))' % self._gap_init_() return PermutationGroup(gap_group=s) def is_commutative(self): diff --git a/src/sage/groups/abelian_gps/abelian_group_gap.py b/src/sage/groups/abelian_gps/abelian_group_gap.py index 04ebb9d3ed1..3a183ab9a20 100644 --- a/src/sage/groups/abelian_gps/abelian_group_gap.py +++ b/src/sage/groups/abelian_gps/abelian_group_gap.py @@ -816,7 +816,7 @@ def _repr_(self): Subgroup of Abelian group with gap, generator orders (2, 3, 4, 5) generated by (f1, f2) """ - return "Subgroup of %s generated by %s"%(self.ambient(),self.gens()) + return "Subgroup of %s generated by %s" % (self.ambient(),self.gens()) def __reduce__(self): r""" diff --git a/src/sage/groups/abelian_gps/element_base.py b/src/sage/groups/abelian_gps/element_base.py index 6a46bd7f444..0435c9835b9 100644 --- a/src/sage/groups/abelian_gps/element_base.py +++ b/src/sage/groups/abelian_gps/element_base.py @@ -246,7 +246,7 @@ def order(self): M = self.parent() order = M.gens_orders() L = self.exponents() - N = LCM([order[i]/GCD(order[i],L[i]) for i in range(len(order)) if L[i]!=0]) + N = LCM([order[i]/GCD(order[i],L[i]) for i in range(len(order)) if L[i] != 0]) if N == 0: return infinity else: @@ -347,4 +347,4 @@ def is_trivial(self): sage: (b^5).is_trivial() True """ - return all(e==0 for e in self._exponents) + return all(e == 0 for e in self._exponents) diff --git a/src/sage/groups/additive_abelian/additive_abelian_group.py b/src/sage/groups/additive_abelian/additive_abelian_group.py index 358302ffd13..a856f2120fe 100644 --- a/src/sage/groups/additive_abelian/additive_abelian_group.py +++ b/src/sage/groups/additive_abelian/additive_abelian_group.py @@ -259,7 +259,7 @@ def _latex_(self): inv = self.invariants() if not inv: inv = (1,) - terms=[] + terms = [] for i in range(len(inv)): if inv[i] == 0: terms.append('\\ZZ') @@ -284,7 +284,7 @@ def short_name(self): invs = [j.additive_order() for j in self.gens()] if not invs: return "Trivial group" - return " + ".join("Z" if j == +oo else "Z/%s"%j for j in invs) + return " + ".join("Z" if j == +oo else "Z/%s" % j for j in invs) def _module_constructor(self, cover, relations, check=True): r""" @@ -467,5 +467,5 @@ def permutation_group(self): if not self.is_finite(): raise TypeError('Additive Abelian group must be finite') from sage.groups.perm_gps.permgroup import PermutationGroup - s = 'Image(IsomorphismPermGroup(AbelianGroup(%s)))'%(list(self.invariants()),) + s = 'Image(IsomorphismPermGroup(AbelianGroup(%s)))' % (list(self.invariants()),) return PermutationGroup(gap_group=s) diff --git a/src/sage/groups/affine_gps/euclidean_group.py b/src/sage/groups/affine_gps/euclidean_group.py index 07349c40292..47de04c6544 100644 --- a/src/sage/groups/affine_gps/euclidean_group.py +++ b/src/sage/groups/affine_gps/euclidean_group.py @@ -199,7 +199,7 @@ def _latex_(self): sage: latex(G) \mathrm{E}_{6}(\Bold{F}_{5}) """ - return "\\mathrm{E}_{%s}(%s)"%(self.degree(), self.base_ring()._latex_()) + return "\\mathrm{E}_{%s}(%s)" % (self.degree(), self.base_ring()._latex_()) def _repr_(self): """ @@ -210,7 +210,7 @@ def _repr_(self): sage: EuclideanGroup(6, GF(5)) Euclidean Group of degree 6 over Finite Field of size 5 """ - return "Euclidean Group of degree %s over %s"%(self.degree(), self.base_ring()) + return "Euclidean Group of degree %s over %s" % (self.degree(), self.base_ring()) def random_element(self): """ diff --git a/src/sage/groups/matrix_gps/finitely_generated_gap.py b/src/sage/groups/matrix_gps/finitely_generated_gap.py index 5864f64afd3..fcfb223b58d 100644 --- a/src/sage/groups/matrix_gps/finitely_generated_gap.py +++ b/src/sage/groups/matrix_gps/finitely_generated_gap.py @@ -922,7 +922,7 @@ def invariants_of_degree(self, deg, chi=None, R=None): inv = set() for e in IntegerVectors(deg, D): F = self.reynolds_operator(R.monomial(*e), chi=chi) - if not F.is_zero() and _new_invariant_is_linearly_independent((F:=F/F.lc()), inv): + if not F.is_zero() and _new_invariant_is_linearly_independent((F := F/F.lc()), inv): inv.add(F) if len(inv) == ms[deg]: break @@ -940,6 +940,6 @@ def _new_invariant_is_linearly_independent(F, invariants): sage: len(s) # needs sage.rings.number_field 3 """ - if len(invariants)==0: + if len(invariants) == 0: return True return PolynomialSequence(invariants).coefficient_matrix()[0].rank() != PolynomialSequence(list(invariants)+[F]).coefficient_matrix()[0].rank() diff --git a/src/sage/groups/matrix_gps/isometries.py b/src/sage/groups/matrix_gps/isometries.py index cbc88ccb184..424e5a0edf0 100644 --- a/src/sage/groups/matrix_gps/isometries.py +++ b/src/sage/groups/matrix_gps/isometries.py @@ -151,11 +151,11 @@ def _repr_(self): n = self.ngens() from sage.repl.display.util import format_list if n > 5: - return 'Group of isometries with %s generators '%n + return 'Group of isometries with %s generators ' % n elif n == 1: - return 'Group of isometries with %s generator %s'%(n, format_list(self.gens())) + return 'Group of isometries with %s generator %s' % (n, format_list(self.gens())) else: - return 'Group of isometries with %s generators %s'%(n, format_list(self.gens())) + return 'Group of isometries with %s generators %s' % (n, format_list(self.gens())) def __reduce__(self): r""" diff --git a/src/sage/groups/matrix_gps/orthogonal.py b/src/sage/groups/matrix_gps/orthogonal.py index b05be536955..c91560f77c7 100644 --- a/src/sage/groups/matrix_gps/orthogonal.py +++ b/src/sage/groups/matrix_gps/orthogonal.py @@ -132,7 +132,7 @@ def normalize_args_e(degree, ring, e): ... ValueError: must have e=-1 or e=1 for even degree """ - if isinstance(ring, FiniteField) and degree%2 == 0: + if isinstance(ring, FiniteField) and degree % 2 == 0: if e not in (-1, +1): raise ValueError('must have e=-1 or e=1 for even degree') else: @@ -167,10 +167,10 @@ def _OG(n, R, special, e=0, var='a', invariant_form=None): NotImplementedError: invariant_form for finite groups is fixed by GAP """ prefix = 'General' - ltx_prefix ='G' + ltx_prefix = 'G' if special: prefix = 'Special' - ltx_prefix ='S' + ltx_prefix = 'S' degree, ring = normalize_args_vectorspace(n, R, var=var) e = normalize_args_e(degree, ring, e) @@ -538,5 +538,5 @@ def _check_matrix(self, x, *args): if F == self.one().matrix(): raise TypeError('matrix must be orthogonal') else: - raise TypeError('matrix must be orthogonal with respect to the symmetric form\n%s' %(F)) + raise TypeError('matrix must be orthogonal with respect to the symmetric form\n%s' % (F)) # TODO: check that quadratic form is preserved in characteristic two diff --git a/src/sage/groups/matrix_gps/unitary.py b/src/sage/groups/matrix_gps/unitary.py index 22dd25b1a4b..4fbb1f1e74f 100644 --- a/src/sage/groups/matrix_gps/unitary.py +++ b/src/sage/groups/matrix_gps/unitary.py @@ -104,10 +104,10 @@ def _UG(n, R, special, var='a', invariant_form=None): 3961191000000 """ prefix = 'General' - latex_prefix ='G' + latex_prefix = 'G' if special: prefix = 'Special' - latex_prefix ='S' + latex_prefix = 'S' degree, ring = normalize_args_vectorspace(n, R, var=var) if isinstance(ring, FiniteField): diff --git a/src/sage/groups/perm_gps/permgroup.py b/src/sage/groups/perm_gps/permgroup.py index cf2ed82f239..b0083394cb0 100644 --- a/src/sage/groups/perm_gps/permgroup.py +++ b/src/sage/groups/perm_gps/permgroup.py @@ -631,7 +631,7 @@ def _gap_init_(self): sage: A4._gap_init_() 'Group([PermList([1, 3, 4, 2]), PermList([2, 3, 1, 4])])' """ - return 'Group([%s])'%(', '.join([g._gap_init_() for g in self.gens()])) + return 'Group([%s])' % (', '.join([g._gap_init_() for g in self.gens()])) @cached_method def gap(self): @@ -736,7 +736,7 @@ def _magma_init_(self, magma): 'PermutationGroup<3 | (1,2,3), (1,2)>' """ g = ', '.join([g._gap_cycle_string() for g in self.gens()]) - return 'PermutationGroup<%s | %s>'%(self.degree(), g) + return 'PermutationGroup<%s | %s>' % (self.degree(), g) def __richcmp__(self, right, op): """ diff --git a/src/sage/groups/perm_gps/permgroup_named.py b/src/sage/groups/perm_gps/permgroup_named.py index 14187399ba6..cc49efd505c 100644 --- a/src/sage/groups/perm_gps/permgroup_named.py +++ b/src/sage/groups/perm_gps/permgroup_named.py @@ -716,7 +716,7 @@ def _repr_(self): sage: A = AlternatingGroup([2,3,7]); A Alternating group of order 3!/2 as a permutation group """ - return "Alternating group of order %s!/2 as a permutation group"%self.degree() + return "Alternating group of order %s!/2 as a permutation group" % self.degree() def _gap_init_(self, gap=None): """ @@ -782,7 +782,7 @@ def _repr_(self): sage: CyclicPermutationGroup(8) Cyclic group of order 8 as a permutation group """ - return "Cyclic group of order %s as a permutation group"%self.order() + return "Cyclic group of order %s as a permutation group" % self.order() def is_commutative(self): """ @@ -975,7 +975,7 @@ def __init__(self, n): # 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) + 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: @@ -990,7 +990,7 @@ def _repr_(self): sage: DiCyclicGroup(12) Dicyclic group of order 48 as a permutation group """ - return "Dicyclic group of order %s as a permutation group"%self.order() + return "Dicyclic group of order %s as a permutation group" % self.order() def is_commutative(self): r""" @@ -1809,7 +1809,7 @@ 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): @@ -1919,7 +1919,7 @@ def _repr_(self): sage: G = TransitiveGroup(1,1); G Transitive group number 1 of degree 1 """ - return "Transitive group number %s of degree %s"%(self._n, self._d) + return "Transitive group number %s of degree %s" % (self._n, self._d) def TransitiveGroups(d=None): @@ -2496,7 +2496,7 @@ def _repr_(self): sage: PrimitiveGroups(6) Primitive Groups of degree 6 """ - return "Primitive Groups of degree %s"%(self._degree) + return "Primitive Groups of degree %s" % (self._degree) def __contains__(self, G): r""" @@ -2689,7 +2689,7 @@ def __str__(self): sage: print(G) The projective general linear group of degree 2 over Finite Field of size 3 """ - return "The projective general linear group of degree %s over %s"%(self._n, self.base_ring()) + return "The projective general linear group of degree %s over %s" % (self._n, self.base_ring()) class PSL(PermutationGroup_plg): @@ -2776,7 +2776,7 @@ def __str__(self): sage: print(G) The projective special linear group of degree 2 over Finite Field of size 3 """ - return "The projective special linear group of degree %s over %s"%(self._n, self.base_ring()) + return "The projective special linear group of degree %s over %s" % (self._n, self.base_ring()) def ramification_module_decomposition_hurwitz_curve(self): r""" @@ -2935,7 +2935,7 @@ def __str__(self): sage: print(G) The projective symplectic linear group of degree 4 over Finite Field of size 3 """ - return "The projective symplectic linear group of degree %s over %s"%(self._n, self.base_ring()) + return "The projective symplectic linear group of degree %s over %s" % (self._n, self.base_ring()) PSP = PSp @@ -3054,7 +3054,7 @@ def _repr_(self): The projective general unitary group of degree 2 over Finite Field of size 3 """ - return "The projective general unitary group of degree %s over %s"%(self._n, self.base_ring()) + return "The projective general unitary group of degree %s over %s" % (self._n, self.base_ring()) class SuzukiGroup(PermutationGroup_unique): @@ -3535,7 +3535,7 @@ def _repr_(self): sage: G = SmallPermutationGroup(12,4); G Group of order 12 and GAP Id 4 as a permutation group """ - return "Group of order %s and GAP Id %s as a permutation group"%(self._n, self._gap_id) + return "Group of order %s and GAP Id %s as a permutation group" % (self._n, self._gap_id) def order(self): """ diff --git a/src/sage/interacts/library.py b/src/sage/interacts/library.py index ccb8fc6d3c2..11035c241df 100644 --- a/src/sage/interacts/library.py +++ b/src/sage/interacts/library.py @@ -429,7 +429,7 @@ def difference_quotient(title, f, interval, a, x0): html('

Difference Quotient

') show(fplot + tanplot + points + dashline + measure, xmin=interval[0], xmax=interval[1], ymin=fmin-0.2*f_height, ymax=fmax) html(r"
$\text{Line's equation:}$") - html(r"$y = %s$
"%tanf(x)) + html(r"$y = %s$
" % tanf(x)) html(r"$\text{Slope:}$") html(r"$k = \frac{f(x_0)-f(a)}{x_0-a} = %s$
" % (N(derivative(tanf(x), x), digits=5))) @@ -941,7 +941,7 @@ def _bisection_method(f, a, b, maxn, eps): elif fc*fb < 0: a, b = c, b else: - raise ValueError("f must have a sign change in the interval (%s,%s)"%(a,b)) + raise ValueError("f must have a sign change in the interval (%s,%s)" % (a,b)) intervals.append((a,b)) round += 1 return c, intervals @@ -956,12 +956,12 @@ def _bisection_method(f, a, b, maxn, eps): print("f must have opposite sign at the endpoints of the interval") show(plot(f, a, b, color='red'), xmin=a, xmax=b) else: - html(r"$\text{Precision }h = 10^{-d}=10^{-%s}=%.5f$"%(d, float(h))) - html(r"${c = }%s$"%latex(c)) - html(r"${f(c) = }%s"%latex(f(c))) - html(r"$%s \text{ iterations}"%len(intervals)) + html(r"$\text{Precision }h = 10^{-d}=10^{-%s}=%.5f$" % (d, float(h))) + html(r"${c = }%s$" % latex(c)) + html(r"${f(c) = }%s" % latex(f(c))) + html(r"$%s \text{ iterations}" % len(intervals)) P = plot(f, a, b, color='red') - k = (P.ymax() - P.ymin())/ (1.5*len(intervals)) + k = (P.ymax() - P.ymin()) / (1.5*len(intervals)) L = sum(line([(c,k*i), (d,k*i)]) for i, (c,d) in enumerate(intervals) ) L += sum(line([(c,k*i-k/4), (c,k*i+k/4)]) for i, (c,d) in enumerate(intervals) ) L += sum(line([(d,k*i-k/4), (d,k*i+k/4)]) for i, (c,d) in enumerate(intervals) ) @@ -1024,12 +1024,12 @@ def _secant_method(f, a, b, maxn, h): show(plot(f, a, b, color='red'), xmin=a, xmax=b) else: c, intervals = _secant_method(f, float(a), float(b), maxn, h) - html(r"$\text{Precision }h = 10^{-d}=10^{-%s}=%.5f$"%(d, float(h))) - html(r"${c = }%s$"%latex(c)) - html(r"${f(c) = }%s"%latex(f(c))) - html(r"$%s \text{ iterations}"%len(intervals)) + html(r"$\text{Precision }h = 10^{-d}=10^{-%s}=%.5f$" % (d, float(h))) + html(r"${c = }%s$" % latex(c)) + html(r"${f(c) = }%s" % latex(f(c))) + html(r"$%s \text{ iterations}" % len(intervals)) P = plot(f, a, b, color='red') - k = (P.ymax() - P.ymin())/ (1.5*len(intervals)) + k = (P.ymax() - P.ymin()) / (1.5*len(intervals)) L = sum(line([(c,k*i), (d,k*i)]) for i, (c,d) in enumerate(intervals) ) L += sum(line([(c,k*i-k/4), (c,k*i+k/4)]) for i, (c,d) in enumerate(intervals) ) L += sum(line([(d,k*i-k/4), (d,k*i+k/4)]) for i, (c,d) in enumerate(intervals) ) @@ -1094,10 +1094,10 @@ def _newton_method(f, c, maxn, h): a, b = interval h = 10**(-d) c, midpoints = _newton_method(f, float(c), maxn, 0.5 * h) - html(r"$\text{Precision } 2h = %s$"%latex(float(h))) - html(r"${c = }%s$"%c) - html(r"${f(c) = }%s"%latex(f(c))) - html(r"$%s \text{ iterations}"%len(midpoints)) + html(r"$\text{Precision } 2h = %s$" % latex(float(h))) + html(r"${c = }%s$" % c) + html(r"${f(c) = }%s" % latex(f(c))) + html(r"$%s \text{ iterations}" % len(midpoints)) if list_steps: s = [["$n$", "$x_n$", "$f(x_n)$", r"$f(x_n-h)\,f(x_n+h)$"]] for i, c in enumerate(midpoints): @@ -1183,26 +1183,26 @@ def trapezoid_integration( xs.append(xi + h) ys.append(f(xi + h)) - html(r'Function $f(x)=%s$'%latex(f(x))) + html(r'Function $f(x)=%s$' % latex(f(x))) show(plot(f, interval[0], interval[1]) + trapezoids, xmin=interval[0], xmax=interval[1]) numeric_value = integral_numerical(f, interval[0], interval[1])[0] - approx = h *(ys[0]/2 + sum([ys[i] for i in range(1,n)]) + ys[n]/2) + approx = h * (ys[0]/2 + sum([ys[i] for i in range(1,n)]) + ys[n]/2) - html(r'Integral value to seven decimal places is: $\displaystyle\int_{%.2f}^{%.2f} {f(x) \, \mathrm{d}x} = %.6f$'%( + html(r'Integral value to seven decimal places is: $\displaystyle\int_{%.2f}^{%.2f} {f(x) \, \mathrm{d}x} = %.6f$' % ( interval[0], interval[1], N(numeric_value, digits=7)) ) if output_form == 'traditional': sum_formula_html = r"\frac {d}{2} \cdot \left[f(x_0) + %s + f(x_{%s})\right]" % ( - ' + '.join([ "2 f(x_{%s})"%i for i in range(1,n)]), + ' + '.join([ "2 f(x_{%s})" % i for i in range(1,n)]), n ) sum_placement_html = r"\frac{%.2f}{2} \cdot \left[f(%.2f) + %s + f(%.2f)\right]" % ( h, N(xs[0], digits=5), - ' + '.join([ "2 f(%.2f)" %N(i, digits=5) for i in xs[1:-1]]), + ' + '.join([ "2 f(%.2f)" % N(i, digits=5) for i in xs[1:-1]]), N(xs[n], digits=5) ) sum_values_html = r"\frac{%.2f}{2} \cdot \left[%.2f + %s + %.2f\right]" % ( @@ -1230,7 +1230,7 @@ def trapezoid_integration( elif output_form == 'table': s = [['$i$', '$x_i$', '$f(x_i)$', '$m$', r'$m\cdot f(x_i)$']] for i in range(0,n+1): - if i==0 or i==n: + if i == 0 or i == n: j = 1 else: j = 2 @@ -1305,7 +1305,7 @@ def simpson_integration( def parabola(a, b, c): from sage.symbolic.relation import solve A, B, C = SR.var("A, B, C") - K = solve([A*a[0]**2+B*a[0]+C==a[1], A*b[0]**2+B*b[0]+C==b[1], A*c[0]**2+B*c[0]+C==c[1]], [A, B, C], solution_dict=True)[0] + K = solve([A*a[0]**2+B*a[0]+C == a[1], A*b[0]**2+B*b[0]+C == b[1], A*c[0]**2+B*c[0]+C == c[1]], [A, B, C], solution_dict=True)[0] f = K[A]*x**2+K[B]*x+K[C] return f xs = [] @@ -1327,36 +1327,36 @@ def parabola(a, b, c): lines += line([(xs[-1],ys[-1]), (xs[-1],0)], color="red") - html(r'Function $f(x)=%s$'%latex(f(x))) + html(r'Function $f(x)=%s$' % latex(f(x))) show(plot(f(x), x, interval[0], interval[1]) + parabolas + lines, xmin=interval[0], xmax=interval[1]) numeric_value = integral_numerical(f,interval[0],interval[1])[0] - approx = dx/3 *(ys[0] + sum([4*ys[i] for i in range(1,n,2)]) + sum([2*ys[i] for i in range(2,n,2)]) + ys[n]) + approx = dx/3 * (ys[0] + sum([4*ys[i] for i in range(1,n,2)]) + sum([2*ys[i] for i in range(2,n,2)]) + ys[n]) - html(r'Integral value to seven decimal places is: $\displaystyle\int_{%.2f}^{%.2f} {f(x) \, \mathrm{d}x} = %.6f$'% + html(r'Integral value to seven decimal places is: $\displaystyle\int_{%.2f}^{%.2f} {f(x) \, \mathrm{d}x} = %.6f$' % (interval[0],interval[1], N(numeric_value,digits=7))) if output_form == 'traditional': sum_formula_html = r"\frac{d}{3} \cdot \left[ f(x_0) + %s + f(x_{%s})\right]" % ( - ' + '.join([ r"%s \cdot f(x_{%s})" %(i%2*(-2)+4, i+1) for i in range(0,n-1)]), + ' + '.join([ r"%s \cdot f(x_{%s})" % (i % 2*(-2)+4, i+1) for i in range(0,n-1)]), n ) sum_placement_html = r"\frac{%.2f}{3} \cdot \left[ f(%.2f) + %s + f(%.2f)\right]" % ( dx, N(xs[0],digits=5), - ' + '.join([ r"%s \cdot f(%.2f)" %(i%2*(-2)+4, N(xk, digits=5)) for i, xk in enumerate(xs[1:-1])]), + ' + '.join([ r"%s \cdot f(%.2f)" % (i % 2*(-2)+4, N(xk, digits=5)) for i, xk in enumerate(xs[1:-1])]), N(xs[n],digits=5) ) - sum_values_html = r"\frac{%.2f}{3} \cdot \left[ %s %s %s\right]" %( + sum_values_html = r"\frac{%.2f}{3} \cdot \left[ %s %s %s\right]" % ( dx, - "%.2f + "%N(ys[0],digits=5), - ' + '.join([ r"%s \cdot %.2f" %(i%2*(-2)+4, N(yk, digits=5)) for i, yk in enumerate(ys[1:-1])]), - " + %.2f"%N(ys[n],digits=5) + "%.2f + " % N(ys[0],digits=5), + ' + '.join([ r"%s \cdot %.2f" % (i % 2*(-2)+4, N(yk, digits=5)) for i, yk in enumerate(ys[1:-1])]), + " + %.2f" % N(ys[n],digits=5) ) html(r''' @@ -1377,14 +1377,14 @@ def parabola(a, b, c): elif output_form == 'table': s = [['$i$', '$x_i$', '$f(x_i)$', '$m$', r'$m\cdot f(x_i)$']] for i in range(0,n+1): - if i==0 or i==n: + if i == 0 or i == n: j = 1 else: - j = (i+1)%2*(-2)+4 + j = (i+1) % 2*(-2)+4 s.append([i, xs[i], ys[i],j,N(j*ys[i])]) s.append(['', '', '', r'$\sum$', '$%s$' % latex(3/dx*approx)]) pretty_print(table(s, header_row=True)) - html(r'$\int_{%.2f}^{%.2f} {f(x) \, \mathrm{d}x}\approx\frac {%.2f}{3}\cdot %s=%s$'% + 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))) @@ -1466,18 +1466,18 @@ def riemann_sum( ys = [func(x_val) for x_val in xs] rects = Graphics() for i in range(n): - body=[[division[i],0],[division[i],ys[i]],[division[i+1],ys[i]],[division[i+1],0]] - if ys[i].n()>0: - color_rect='green' + body = [[division[i],0],[division[i],ys[i]],[division[i+1],ys[i]],[division[i+1],0]] + if ys[i].n() > 0: + color_rect = 'green' else: - color_rect='red' + color_rect = 'red' rects = rects + polygon2d(body, rgbcolor=color_rect, alpha=0.1)\ + point((xs[i], ys[i]), rgbcolor=(1, 0, 0))\ + line(body, rgbcolor='black', zorder=-1) html('Adjust your data and click Update button. Click repeatedly for another random values.') show(plot(func(x),(x,a,b),zorder=5) + rects) - delka_intervalu=[division[i+1]-division[i] for i in range(n)] + delka_intervalu = [division[i+1]-division[i] for i in range(n)] if list_table: pretty_print(table([ ["$i$", "$[x_{i-1},x_i]$", r"$\eta_i$", r"$f(\eta_i)$", "$x_{i}-x_{i-1}$"] @@ -1485,9 +1485,9 @@ def riemann_sum( [i+1,[division[i],division[i+1]],xs[i],ys[i],delka_intervalu[i]] for i in range(n) ], header_row=True)) - html(r'Riemann sum: $\displaystyle\sum_{i=1}^{%s} f(\eta_i)(x_i-x_{i-1})=%s$ '% + html(r'Riemann sum: $\displaystyle\sum_{i=1}^{%s} f(\eta_i)(x_i-x_{i-1})=%s$ ' % (latex(n),latex(sum([ys[i]*delka_intervalu[i] for i in range(n)])))) - html(r'Exact value of the integral $\displaystyle\int_{%s}^{%s}%s\,\mathrm{d}x=%s$'% + html(r'Exact value of the integral $\displaystyle\int_{%s}^{%s}%s\,\mathrm{d}x=%s$' % (latex(a),latex(b),latex(func(x)),latex(integral_numerical(func(x),a,b)[0]))) @@ -1633,9 +1633,9 @@ def function_tool(f, g, xrange, yrange, a, action, do_plot): elif action == 'f(g)': h = f(g) lbl = 'f(g)' - html('
$f = %s$
'%latex(f)) - html('
$g = %s$
'%latex(g)) - html('
$h = %s = %s$
'%(lbl, latex(h))) + html('
$f = %s$
' % latex(f)) + html('
$g = %s$
' % latex(g)) + html('
$h = %s = %s$
' % (lbl, latex(h))) if do_plot: P = plot(f, xrange, color='red', thickness=2) + \ plot(g, xrange, color='green', thickness=2) + \ @@ -1789,7 +1789,7 @@ def cellular_automaton(N, rule_number, size): binary_digits = Integer(rule_number).digits(base=2) rule = binary_digits + [0]*(8-len(binary_digits)) - html('

Cellular Automaton

'+ + html('

Cellular Automaton

' + '
"A cellular automaton is a collection of "colored" cells \ on a grid of specified shape that evolves through a number of \ discrete time steps according to a set of rules based on the \ @@ -1923,7 +1923,7 @@ def polar_prime_spiral(interval, show_factors, highlight_primes, show_curves, n, m = SR.var('m') g = symbolic_expression(a*m**2+b*m+c).function(m) r = symbolic_expression(sqrt(g(m))).function(m) - theta = symbolic_expression(r(m)- m*sqrt(a)).function(m) + theta = symbolic_expression(r(m) - m*sqrt(a)).function(m) S1 = parametric_plot(((r(t))*cos(2*pi*(theta(t))),(r(t))*sin(2*pi*(theta(t)))), (begin_curve, ceil(sqrt(end-start))), color=hue(0.8), thickness=.3) # pink line @@ -1932,7 +1932,7 @@ def polar_prime_spiral(interval, show_factors, highlight_primes, show_curves, n, c = c2 g = symbolic_expression(a*m**2+b*m+c).function(m) r = symbolic_expression(sqrt(g(m))).function(m) - theta = symbolic_expression(r(m)- m*sqrt(a)).function(m) + theta = symbolic_expression(r(m) - m*sqrt(a)).function(m) S2 = parametric_plot(((r(t))*cos(2*pi*(theta(t))),(r(t))*sin(2*pi*(theta(t)))), (begin_curve, ceil(sqrt(end-start))), color=hue(0.6), thickness=.3) # green line diff --git a/src/sage/libs/coxeter3/coxeter_group.py b/src/sage/libs/coxeter3/coxeter_group.py index 527cfc61c6f..f0d29fec436 100644 --- a/src/sage/libs/coxeter3/coxeter_group.py +++ b/src/sage/libs/coxeter3/coxeter_group.py @@ -72,7 +72,7 @@ def _repr_(self): sage: W = CoxeterGroup(['A', 3, 1], implementation='coxeter3'); W # optional - coxeter3 Coxeter group of type ['A', 3, 1] implemented by Coxeter3 """ - return "Coxeter group of type %s implemented by Coxeter3"%(self.cartan_type()) + return "Coxeter group of type %s implemented by Coxeter3" % (self.cartan_type()) def __iter__(self): """ diff --git a/src/sage/libs/eclib/interface.py b/src/sage/libs/eclib/interface.py index 4c842dca48e..30e286cea16 100644 --- a/src/sage/libs/eclib/interface.py +++ b/src/sage/libs/eclib/interface.py @@ -799,7 +799,7 @@ def __init__(self, curve, verbose=True, pp=1, maxr=999): Subgroup of Mordell-Weil group: [] """ if not isinstance(curve, mwrank_EllipticCurve): - raise TypeError("curve (=%s) must be an mwrank_EllipticCurve"%curve) + raise TypeError("curve (=%s) must be an mwrank_EllipticCurve" % curve) self.__curve = curve self.__verbose = verbose self.__pp = pp @@ -841,7 +841,7 @@ def __repr__(self): sage: EQ.__repr__() 'Subgroup of Mordell-Weil group: [[1:-1:1], [-2:3:1], [-14:25:8]]' """ - return "Subgroup of Mordell-Weil group: %s"%self.__mw + return "Subgroup of Mordell-Weil group: %s" % self.__mw def process(self, v, saturation_bound=0): """Process points in the list ``v``. @@ -988,11 +988,11 @@ def process(self, v, saturation_bound=0): (True, 1, '[ ]') """ if not isinstance(v, list): - raise TypeError("v (=%s) must be a list"%v) + raise TypeError("v (=%s) must be a list" % v) saturation_bound = int(saturation_bound) for P in v: if not isinstance(P, (list, tuple)) or len(P) != 3: - raise TypeError("v (=%s) must be a list of 3-tuples (or 3-element lists) of ints"%v) + raise TypeError("v (=%s) must be a list of 3-tuples (or 3-element lists) of ints" % v) self.__mw.process(P, saturation_bound) def regulator(self): diff --git a/src/sage/manifolds/differentiable/examples/euclidean.py b/src/sage/manifolds/differentiable/examples/euclidean.py index 21ae796fad5..97e3aa3d875 100644 --- a/src/sage/manifolds/differentiable/examples/euclidean.py +++ b/src/sage/manifolds/differentiable/examples/euclidean.py @@ -1832,7 +1832,7 @@ def _init_cylindrical(self, symbols): coords = symbols.split() # list of strings, one per coordinate # Adding the coordinate ranges: coordinates = (coords[0] + ':(0,+oo) ' + coords[1] - + ':(0,2*pi):periodic '+ coords[2]) + + ':(0,2*pi):periodic ' + coords[2]) chart = self.chart(coordinates=coordinates) self._cylindrical_chart = chart frame = chart.frame() diff --git a/src/sage/matrix/benchmark.py b/src/sage/matrix/benchmark.py index 97117632584..5e29a19f48c 100644 --- a/src/sage/matrix/benchmark.py +++ b/src/sage/matrix/benchmark.py @@ -152,13 +152,13 @@ def nullspace_ZZ(n=200, min=0, max=2**32, system='sage'): t := Cputime(); K := Kernel(A); s := Cputime(t); -"""%(n,min,max) +""" % (n,min,max) if verbose: print(code) magma.eval(code) return float(magma.eval('s')) else: - raise ValueError('unknown system "%s"'%system) + raise ValueError('unknown system "%s"' % system) def charpoly_ZZ(n=100, min=0, max=9, system='sage'): @@ -192,13 +192,13 @@ def charpoly_ZZ(n=100, min=0, max=9, system='sage'): t := Cputime(); K := CharacteristicPolynomial(A); s := Cputime(t); -"""%(n,min,max) +""" % (n,min,max) if verbose: print(code) magma.eval(code) return float(magma.eval('s')) else: - raise ValueError('unknown system "%s"'%system) + raise ValueError('unknown system "%s"' % system) def rank_ZZ(n=700, min=0, max=9, system='sage'): @@ -232,13 +232,13 @@ def rank_ZZ(n=700, min=0, max=9, system='sage'): t := Cputime(); K := Rank(A); s := Cputime(t); -"""%(n,min,max) +""" % (n,min,max) if verbose: print(code) magma.eval(code) return float(magma.eval('s')) else: - raise ValueError('unknown system "%s"'%system) + raise ValueError('unknown system "%s"' % system) def rank2_ZZ(n=400, min=0, max=2**64, system='sage'): """ @@ -271,13 +271,13 @@ def rank2_ZZ(n=400, min=0, max=2**64, system='sage'): t := Cputime(); K := Rank(A); s := Cputime(t); -"""%(n,min,max) +""" % (n,min,max) if verbose: print(code) magma.eval(code) return float(magma.eval('s')) else: - raise ValueError('unknown system "%s"'%system) + raise ValueError('unknown system "%s"' % system) # Smith Form @@ -312,13 +312,13 @@ def smithform_ZZ(n=128, min=0, max=9, system='sage'): t := Cputime(); K := ElementaryDivisors(A); s := Cputime(t); -"""%(n,min,max) +""" % (n,min,max) if verbose: print(code) magma.eval(code) return float(magma.eval('s')) else: - raise ValueError('unknown system "%s"'%system) + raise ValueError('unknown system "%s"' % system) def matrix_multiply_ZZ(n=300, min=-9, max=9, system='sage', times=1): @@ -358,13 +358,13 @@ def matrix_multiply_ZZ(n=300, min=-9, max=9, system='sage', times=1): K := A * B; end for; s := Cputime(t); -"""%(n,min,max,times) +""" % (n,min,max,times) if verbose: print(code) magma.eval(code) return float(magma.eval('s'))/times else: - raise ValueError('unknown system "%s"'%system) + raise ValueError('unknown system "%s"' % system) def matrix_add_ZZ(n=200, min=-9, max=9, system='sage', times=50): """ @@ -405,13 +405,13 @@ def matrix_add_ZZ(n=200, min=-9, max=9, system='sage', times=50): K := A + B; end for; s := Cputime(t); -"""%(n,min,max,times) +""" % (n,min,max,times) if verbose: print(code) magma.eval(code) return float(magma.eval('s'))/times else: - raise ValueError('unknown system "%s"'%system) + raise ValueError('unknown system "%s"' % system) def matrix_add_ZZ_2(n=200, bits=16, system='sage', times=50): """ @@ -466,13 +466,13 @@ def det_ZZ(n=200, min=1, max=100, system='sage'): t := Cputime(); d := Determinant(A); s := Cputime(t); -"""%(n,min,max) +""" % (n,min,max) if verbose: print(code) magma.eval(code) return float(magma.eval('s')) else: - raise ValueError('unknown system "%s"'%system) + raise ValueError('unknown system "%s"' % system) def det_QQ(n=300, num_bound=10, den_bound=10, system='sage'): @@ -507,13 +507,13 @@ def det_QQ(n=300, num_bound=10, den_bound=10, system='sage'): t := Cputime(); d := Determinant(A); s := Cputime(t); -"""%(n,-num_bound, num_bound, den_bound) +""" % (n,-num_bound, num_bound, den_bound) if verbose: print(code) magma.eval(code) return float(magma.eval('s')) else: - raise ValueError('unknown system "%s"'%system) + raise ValueError('unknown system "%s"' % system) def vecmat_ZZ(n=300, min=-9, max=9, system='sage', times=200): @@ -555,13 +555,13 @@ def vecmat_ZZ(n=300, min=-9, max=9, system='sage', times=200): K := v * A; end for; s := Cputime(t); -"""%(n,min,max,times) +""" % (n,min,max,times) if verbose: print(code) magma.eval(code) return float(magma.eval('s'))/times else: - raise ValueError('unknown system "%s"'%system) + raise ValueError('unknown system "%s"' % system) ####################################################################### @@ -631,13 +631,13 @@ def nullspace_GF(n=300, p=16411, system='sage'): t := Cputime(); K := Kernel(A); s := Cputime(t); -"""%(n,p) +""" % (n,p) if verbose: print(code) magma.eval(code) return magma.eval('s') else: - raise ValueError('unknown system "%s"'%system) + raise ValueError('unknown system "%s"' % system) # Characteristic Polynomial over GF @@ -671,13 +671,13 @@ def charpoly_GF(n=100, p=16411, system='sage'): t := Cputime(); K := CharacteristicPolynomial(A); s := Cputime(t); -"""%(n,p) +""" % (n,p) if verbose: print(code) magma.eval(code) return magma.eval('s') else: - raise ValueError('unknown system "%s"'%system) + raise ValueError('unknown system "%s"' % system) def matrix_add_GF(n=1000, p=16411, system='sage',times=100): """ @@ -713,13 +713,13 @@ def matrix_add_GF(n=1000, p=16411, system='sage',times=100): K := A + B; end for; s := Cputime(t); -"""%(n,p,p,times) +""" % (n,p,p,times) if verbose: print(code) magma.eval(code) return magma.eval('s') else: - raise ValueError('unknown system "%s"'%system) + raise ValueError('unknown system "%s"' % system) # Matrix multiplication over GF(p) @@ -759,13 +759,13 @@ def matrix_multiply_GF(n=100, p=16411, system='sage', times=3): K := A * B; end for; s := Cputime(t); -"""%(n,p,times) +""" % (n,p,times) if verbose: print(code) magma.eval(code) return float(magma.eval('s'))/times else: - raise ValueError('unknown system "%s"'%system) + raise ValueError('unknown system "%s"' % system) def rank_GF(n=500, p=16411, system='sage'): @@ -797,13 +797,13 @@ def rank_GF(n=500, p=16411, system='sage'): t := Cputime(); K := Rank(A); s := Cputime(t); -"""%(n,p) +""" % (n,p) if verbose: print(code) magma.eval(code) return float(magma.eval('s')) else: - raise ValueError('unknown system "%s"'%system) + raise ValueError('unknown system "%s"' % system) def rank2_GF(n=500, p=16411, system='sage'): """ @@ -834,13 +834,13 @@ def rank2_GF(n=500, p=16411, system='sage'): t := Cputime(); K := Rank(A); s := Cputime(t); -"""%(n,p) +""" % (n,p) if verbose: print(code) magma.eval(code) return float(magma.eval('s')) else: - raise ValueError('unknown system "%s"'%system) + raise ValueError('unknown system "%s"' % system) def det_GF(n=400, p=16411 , system='sage'): """ @@ -872,13 +872,13 @@ def det_GF(n=400, p=16411 , system='sage'): t := Cputime(); d := Determinant(A); s := Cputime(t); -"""%(n,p) +""" % (n,p) if verbose: print(code) magma.eval(code) return float(magma.eval('s')) else: - raise ValueError('unknown system "%s"'%system) + raise ValueError('unknown system "%s"' % system) ####################################################################### @@ -935,13 +935,13 @@ def echelon_QQ(n=100, min=0, max=9, system='sage'): t := Cputime(); K := EchelonForm(A); s := Cputime(t); -"""%(n,min,max) +""" % (n,min,max) if verbose: print(code) magma.eval(code) return float(magma.eval('s')) else: - raise ValueError('unknown system "%s"'%system) + raise ValueError('unknown system "%s"' % system) # Invert a matrix over QQ. @@ -975,13 +975,13 @@ def inverse_QQ(n=100, min=0, max=9, system='sage'): t := Cputime(); K := A^(-1); s := Cputime(t); -"""%(n,min,max) +""" % (n,min,max) if verbose: print(code) magma.eval(code) return float(magma.eval('s')) else: - raise ValueError('unknown system "%s"'%system) + raise ValueError('unknown system "%s"' % system) # Matrix multiplication over QQ @@ -1022,13 +1022,13 @@ def matrix_multiply_QQ(n=100, bnd=2, system='sage', times=1): K := A * B; end for; s := Cputime(t); -"""%(n, A.name(), times) +""" % (n, A.name(), times) if verbose: print(code) magma.eval(code) return float(magma.eval('s'))/times else: - raise ValueError('unknown system "%s"'%system) + raise ValueError('unknown system "%s"' % system) # Determinant of Hilbert matrix @@ -1060,7 +1060,7 @@ def det_hilbert_QQ(n=80, system='sage'): d := Determinant(h); s := Cputime(tinit); delete h; -"""%n +""" % n if verbose: print(code) magma.eval(code) @@ -1095,7 +1095,7 @@ def invert_hilbert_QQ(n=40, system='sage'): d := h^(-1); s := Cputime(tinit); delete h; -"""%n +""" % n if verbose: print(code) magma.eval(code) @@ -1119,13 +1119,13 @@ def MatrixVector_QQ(n=1000,h=100,system='sage',times=1): sage: ts = b.MatrixVector_QQ(500) sage: tm = b.MatrixVector_QQ(500, system='magma') # optional - magma """ - if system=='sage': - V=QQ**n - v=V.random_element(h) - M=random_matrix(QQ,n) - t=cputime() + if system == 'sage': + V = QQ**n + v = V.random_element(h) + M = random_matrix(QQ,n) + t = cputime() for i in range(times): - w=M*v + w = M*v return cputime(t) elif system == 'magma': code = """ @@ -1139,13 +1139,13 @@ def MatrixVector_QQ(n=1000,h=100,system='sage',times=1): W:=v*M; end for; s := Cputime(t); - """%(n,h,times) + """ % (n,h,times) if verbose: print(code) magma.eval(code) return float(magma.eval('s')) else: - raise ValueError('unknown system "%s"'%system) + raise ValueError('unknown system "%s"' % system) ####################################################################### @@ -1188,13 +1188,13 @@ def nullspace_RR(n=300, min=0, max=10, system='sage'): t := Cputime(); K := Kernel(A); s := Cputime(t); -"""%(n,min,max) +""" % (n,min,max) if verbose: print(code) magma.eval(code) return float(magma.eval('s')) else: - raise ValueError('unknown system "%s"'%system) + raise ValueError('unknown system "%s"' % system) def nullspace_RDF(n=300, min=0, max=10, system='sage'): diff --git a/src/sage/matrix/matrix_integer_dense_saturation.py b/src/sage/matrix/matrix_integer_dense_saturation.py index 365c8d830bf..66f56608def 100644 --- a/src/sage/matrix/matrix_integer_dense_saturation.py +++ b/src/sage/matrix/matrix_integer_dense_saturation.py @@ -46,7 +46,7 @@ def p_saturation(A, p, proof=True): sage: C3.index_in_saturation() 2 """ - tm = verbose("%s-saturating a %sx%s matrix"%(p, A.nrows(), A.ncols())) + tm = verbose("%s-saturating a %sx%s matrix" % (p, A.nrows(), A.ncols())) H = A.hermite_form(include_zero_rows=False, proof=proof) while True: if p == 2: @@ -256,7 +256,7 @@ def saturation(A, proof=True, p=0, max_dets=5): v = random_sublist_of_size(nc, nr) tm = verbose('saturation -- checking det condition on submatrix') d = gcd(d, A.matrix_from_columns(v).determinant(proof=proof)) - verbose('saturation -- got det down to %s'%d, tm) + verbose('saturation -- got det down to %s' % d, tm) if gcd(d, p) == 1: return A._insert_zero_columns(zero_cols) already_tried.append(v) diff --git a/src/sage/matrix/special.py b/src/sage/matrix/special.py index 41b64965ca3..1aeccd6b3e3 100644 --- a/src/sage/matrix/special.py +++ b/src/sage/matrix/special.py @@ -2555,22 +2555,22 @@ def random_rref_matrix(parent, num_pivots): # Experimental distribution used to generate the values. for non_pivot_column_entry in range(pivot_index+1): sign1 = (2*randint(0,1)-1) - return_matrix[non_pivot_column_entry,non_pivot_column_index]=sign1*int(entry_generator1.get_random_element()*((1-non_pivot_column_entry/return_matrix.ncols())*7)) + return_matrix[non_pivot_column_entry,non_pivot_column_index] = sign1*int(entry_generator1.get_random_element()*((1-non_pivot_column_entry/return_matrix.ncols())*7)) # Use index to fill entries of the columns to the right of the last pivot column. for rest_non_pivot_column in range(pivots[num_pivots-1]+1,num_col): - entry_generator2=pd.RealDistribution("beta",[2.6,4]) + entry_generator2 = pd.RealDistribution("beta",[2.6,4]) # experimental distribution to generate small values. for rest_entries in range(num_pivots): - sign2=(2*randint(0,1)-1) - return_matrix[rest_entries,rest_non_pivot_column]=sign2*int(entry_generator2.get_random_element()*5) + sign2 = (2*randint(0,1)-1) + return_matrix[rest_entries,rest_non_pivot_column] = sign2*int(entry_generator2.get_random_element()*5) else: for pivot_index in range(num_pivots-1): for non_pivot_column_index in range(pivots[pivot_index]+1,pivots[pivot_index+1]): for non_pivot_column_entry in range(pivot_index+1): - return_matrix[non_pivot_column_entry,non_pivot_column_index]=ring.random_element() + return_matrix[non_pivot_column_entry,non_pivot_column_index] = ring.random_element() for rest_non_pivot_column in range(pivots[num_pivots-1]+1,num_col): for rest_entries in range(num_pivots): - return_matrix[rest_entries,rest_non_pivot_column]=ring.random_element() + return_matrix[rest_entries,rest_non_pivot_column] = ring.random_element() return return_matrix @@ -2750,40 +2750,40 @@ def random_echelonizable_matrix(parent, rank, upper_bound=None, max_tries=100): while row_index < rows: # To each row in a pivot column add a scalar multiple of the pivot row. # for full rank, square matrices, using only this row operation preserves the determinant of 1. - if pivots!=row_index: + if pivots != row_index: # To ensure a leading one is not removed by the addition of the pivot row by its # additive inverse. - matrix_copy=matrix.with_added_multiple_of_row(row_index,matrix.pivot_rows()[pivots],randint(-5,5)) + matrix_copy = matrix.with_added_multiple_of_row(row_index,matrix.pivot_rows()[pivots],randint(-5,5)) tries += 1 # Range for scalar multiples determined experimentally. if max(map(abs,matrix_copy.list())) < upper_bound: # Continue if the largest entry after a row operation is within the bound. - matrix=matrix_copy - row_index+=1 + matrix = matrix_copy + row_index += 1 tries = 0 if tries > max_tries: # to prevent endless unsuccessful row adding raise ValueError("tried "+str(max_tries)+" times to get row number "+str(row_index)+". Try bigger upper_bound?") # The leading one in row one has not been altered, so add a scalar multiple of a random row # to row one. - row1=0 - if rows>1: - while row1<1: - matrix_copy=matrix.with_added_multiple_of_row(0,randint(1,rows-1),randint(-3,3)) + row1 = 0 + if rows > 1: + while row1 < 1: + matrix_copy = matrix.with_added_multiple_of_row(0,randint(1,rows-1),randint(-3,3)) if max(map(abs,matrix_copy.list())) < upper_bound: - matrix=matrix_copy - row1+=1 + matrix = matrix_copy + row1 += 1 # If the matrix generated over a different ring, random elements from the designated ring are used as and # the routine is run similarly to the size unchecked version for rationals and integers. else: for pivots in range(rank-1,-1,-1): - row_index=0 - while row_index1: + row_index += 1 + if rows > 1: matrix.add_multiple_of_row(0,randint(1,rows-1),ring.random_element()) return matrix @@ -2911,7 +2911,7 @@ def random_subspaces_matrix(parent, rank=None): left_nullity_generator = pd.RealDistribution("beta", [1.4, 5.5]) nullity = int(left_nullity_generator.get_random_element()*(rows-1) + 1) rank = rows - nullity - if rank<0: + if rank < 0: raise ValueError("matrices must have rank zero or greater.") if rank > rows or rank > columns: raise ValueError("rank cannot exceed the number of rows or columns.") @@ -3028,16 +3028,16 @@ def random_unimodular_matrix(parent, upper_bound=None, max_tries=100): Billy Wonderly (2010-07) """ - ring=parent.base_ring() - size=parent.nrows() - if parent.nrows()!=parent.ncols(): + ring = parent.base_ring() + size = parent.nrows() + if parent.nrows() != parent.ncols(): raise TypeError("a unimodular matrix must be square.") - if upper_bound is not None and (ring!=ZZ and ring!=QQ): + if upper_bound is not None and (ring != ZZ and ring != QQ): raise TypeError("only matrices over ZZ or QQ can have size control.") if upper_bound is None: # random_echelonizable_matrix() always returns a determinant one matrix if given full rank. return random_matrix(ring, size, algorithm='echelonizable', rank=size) - elif upper_bound is not None and (ring==ZZ or ring==QQ): + elif upper_bound is not None and (ring == ZZ or ring == QQ): return random_matrix(ring, size,algorithm='echelonizable',rank=size, upper_bound=upper_bound, max_tries=max_tries) @@ -3226,7 +3226,7 @@ def random_diagonalizable_matrix(parent,eigenvalues=None,dimensions=None): up_bound = up_bound + dimensions[row_index] for entry in range(low_bound,up_bound): diagonal_matrix[entry, entry] = eigenvalues[row_index] - low_bound=low_bound+dimensions[row_index] + low_bound = low_bound+dimensions[row_index] # Create a matrix to hold each of the eigenvectors as its columns, begin with an identity matrix so that after row and column # operations the resulting matrix will be unimodular. eigenvector_matrix = matrix(QQ, size, size, 1) @@ -3234,13 +3234,13 @@ def random_diagonalizable_matrix(parent,eigenvalues=None,dimensions=None): lower_limit = 0 #run the routine over the necessary number of columns corresponding eigenvalue dimension. for dimension_index in range(len(dimensions)-1): - upper_limit=upper_limit+dimensions[dimension_index] - lowest_index_row_with_one=size-dimensions[dimension_index] + upper_limit = upper_limit+dimensions[dimension_index] + lowest_index_row_with_one = size-dimensions[dimension_index] #assign a one to the row that is the eigenvalue dimension rows up from the bottom row then assign ones diagonally down to the right. for eigen_ones in range(lower_limit,upper_limit): - eigenvector_matrix[lowest_index_row_with_one,eigen_ones]=1 - lowest_index_row_with_one+=1 - lower_limit=lower_limit+dimensions[dimension_index] + eigenvector_matrix[lowest_index_row_with_one,eigen_ones] = 1 + lowest_index_row_with_one += 1 + lower_limit = lower_limit+dimensions[dimension_index] #Create a list to give the eigenvalue dimension corresponding to each column. dimension_check = [] for i in range(len(dimensions)): @@ -3248,14 +3248,14 @@ def random_diagonalizable_matrix(parent,eigenvalues=None,dimensions=None): dimension_check.append(dimensions[i]) #run routine over the rows that are in the range of the protected ones. Use addition of column multiples to fill entries. for dimension_multiplicity in range(max(dimensions),min(dimensions),-1): - highest_one_row=size-dimension_multiplicity - highest_one_column=0 + highest_one_row = size-dimension_multiplicity + highest_one_column = 0 #find the column with the protected one in the lowest indexed row. - while eigenvector_matrix[highest_one_row,highest_one_column]==0: - highest_one_column+=1 + while eigenvector_matrix[highest_one_row,highest_one_column] == 0: + highest_one_column += 1 #dimension_check determines if column has a low enough eigenvalue dimension to take a column multiple. for bottom_entry_filler in range(len(dimension_check)): - if dimension_check[bottom_entry_filler] n: - nbc_slack[i -1 - n] = coef + nbc_slack[i - 1 - n] = coef else: nbc_decision[i - 1] = coef if 0 in self.basic_indices() and not sum(nbc_slack) == -1: diff --git a/src/sage/numerical/optimize.py b/src/sage/numerical/optimize.py index 0f578f4e52b..f728b2ad89f 100644 --- a/src/sage/numerical/optimize.py +++ b/src/sage/numerical/optimize.py @@ -390,37 +390,37 @@ def minimize(func, x0, gradient=None, hessian=None, algorithm="default", import numpy from scipy import optimize if isinstance(func, Expression): - var_list=func.variables() + var_list = func.variables() var_names = [str(_) for _ in var_list] - fast_f=fast_callable(func, vars=var_names, domain=float) - f=lambda p: fast_f(*p) - gradient_list=func.gradient() - fast_gradient_functions=[fast_callable(gradient_list[i], vars=var_names, domain=float) for i in range(len(gradient_list))] - gradient=lambda p: numpy.array([ a(*p) for a in fast_gradient_functions]) + fast_f = fast_callable(func, vars=var_names, domain=float) + f = lambda p: fast_f(*p) + gradient_list = func.gradient() + fast_gradient_functions = [fast_callable(gradient_list[i], vars=var_names, domain=float) for i in range(len(gradient_list))] + gradient = lambda p: numpy.array([ a(*p) for a in fast_gradient_functions]) else: - f=func + f = func - if algorithm=="default": + if algorithm == "default": if gradient is None: min = optimize.fmin(f, [float(_) for _ in x0], disp=verbose, **args) else: - min= optimize.fmin_bfgs(f, [float(_) for _ in x0],fprime=gradient, disp=verbose, **args) + min = optimize.fmin_bfgs(f, [float(_) for _ in x0],fprime=gradient, disp=verbose, **args) else: - if algorithm=="simplex": - min= optimize.fmin(f, [float(_) for _ in x0], disp=verbose, **args) - elif algorithm=="bfgs": - min= optimize.fmin_bfgs(f, [float(_) for _ in x0], fprime=gradient, disp=verbose, **args) - elif algorithm=="cg": - min= optimize.fmin_cg(f, [float(_) for _ in x0], fprime=gradient, disp=verbose, **args) - elif algorithm=="powell": - min= optimize.fmin_powell(f, [float(_) for _ in x0], disp=verbose, **args) - elif algorithm=="ncg": + if algorithm == "simplex": + min = optimize.fmin(f, [float(_) for _ in x0], disp=verbose, **args) + elif algorithm == "bfgs": + min = optimize.fmin_bfgs(f, [float(_) for _ in x0], fprime=gradient, disp=verbose, **args) + elif algorithm == "cg": + min = optimize.fmin_cg(f, [float(_) for _ in x0], fprime=gradient, disp=verbose, **args) + elif algorithm == "powell": + min = optimize.fmin_powell(f, [float(_) for _ in x0], disp=verbose, **args) + elif algorithm == "ncg": if isinstance(func, Expression): - hess=func.hessian() - hess_fast= [ [fast_callable(a, vars=var_names, domain=float) for a in row] for row in hess] - hessian=lambda p: [[a(*p) for a in row] for row in hess_fast] + hess = func.hessian() + hess_fast = [ [fast_callable(a, vars=var_names, domain=float) for a in row] for row in hess] + hessian = lambda p: [[a(*p) for a in row] for row in hess_fast] from scipy import dot - hessian_p=lambda p,v: dot(numpy.array(hessian(p)),v) + hessian_p = lambda p,v: dot(numpy.array(hessian(p)),v) min = optimize.fmin_ncg(f, [float(_) for _ in x0], fprime=gradient, fhess=hessian, fhess_p=hessian_p, disp=verbose, **args) return vector(RDF, min) @@ -651,19 +651,19 @@ def linear_program(c, G, h, A=None, b=None, solver=None): from cvxopt.base import matrix as m from cvxopt import solvers - solvers.options['show_progress']=False - if solver=='glpk': + solvers.options['show_progress'] = False + if solver == 'glpk': from cvxopt import glpk glpk.options['LPX_K_MSGLEV'] = 0 - c_=m(c.base_extend(RDF).numpy()) - G_=m(G.base_extend(RDF).numpy()) - h_=m(h.base_extend(RDF).numpy()) + c_ = m(c.base_extend(RDF).numpy()) + G_ = m(G.base_extend(RDF).numpy()) + h_ = m(h.base_extend(RDF).numpy()) if A is not None and b is not None: - A_=m(A.base_extend(RDF).numpy()) - b_=m(b.base_extend(RDF).numpy()) - sol=solvers.lp(c_,G_,h_,A_,b_,solver=solver) + A_ = m(A.base_extend(RDF).numpy()) + b_ = m(b.base_extend(RDF).numpy()) + sol = solvers.lp(c_,G_,h_,A_,b_,solver=solver) else: - sol=solvers.lp(c_,G_,h_,solver=solver) + sol = solvers.lp(c_,G_,h_,solver=solver) status = sol['status'] if status != 'optimal': return {'primal objective': None, 'x': None, 's': None, 'y': None, diff --git a/src/sage/repl/configuration.py b/src/sage/repl/configuration.py index cb255ef65b3..90df44bdf81 100644 --- a/src/sage/repl/configuration.py +++ b/src/sage/repl/configuration.py @@ -133,7 +133,7 @@ def default(self): # TerminalInteractiveShell (note: in fact some configs like term_title # only apply to the latter, but we can still use the same config for # both for simplicity's sake; see Issue #28289) - InteractiveShell=Config( + InteractiveShell = Config( prompts_class=SagePrompts, ast_node_interactivity='all', colors=self.colors(), diff --git a/src/sage/rings/function_field/drinfeld_modules/drinfeld_module.py b/src/sage/rings/function_field/drinfeld_modules/drinfeld_module.py index 74ef125fb6a..bfd4606700b 100644 --- a/src/sage/rings/function_field/drinfeld_modules/drinfeld_module.py +++ b/src/sage/rings/function_field/drinfeld_modules/drinfeld_module.py @@ -1394,9 +1394,9 @@ def _compute_goss_polynomial(self, n, q, poly_ring, X): if n % q == 0: return self.goss_polynomial(n // q)**q # General case - pol = sum(self._compute_coefficient_exp(i+1) - *self._compute_goss_polynomial(n - q**(i+1), q, poly_ring, X) - for i in range(0, (n.log(q).n()).floor())) + pol = sum(self._compute_coefficient_exp(i + 1) + * self._compute_goss_polynomial(n - q**(i+1), q, poly_ring, X) + for i in range((n.log(q).n()).floor())) return X*(self._compute_goss_polynomial(n - 1, q, poly_ring, X) + pol) def goss_polynomial(self, n, var='X'): diff --git a/src/sage/sat/boolean_polynomials.py b/src/sage/sat/boolean_polynomials.py index 2f3e650d70b..80b1a13d89c 100644 --- a/src/sage/sat/boolean_polynomials.py +++ b/src/sage/sat/boolean_polynomials.py @@ -283,7 +283,7 @@ def solve(F, converter=None, solver=None, n=1, target_variables=None, **kwds): try: learnt = solver.learnt_clauses(unitary_only=True) if learnt: - S.append(dict((phi[abs(i)-1], K(i<0)) for i in learnt)) + S.append(dict((phi[abs(i) - 1], K(i < 0)) for i in learnt)) else: S.append(s) break diff --git a/src/sage/sat/solvers/dimacs.py b/src/sage/sat/solvers/dimacs.py index c1ad5409f55..f9688ecd8d6 100644 --- a/src/sage/sat/solvers/dimacs.py +++ b/src/sage/sat/solvers/dimacs.py @@ -105,7 +105,7 @@ def __repr__(self): sage: DIMACS(command="iliketurtles {input}") DIMACS Solver: 'iliketurtles {input}' """ - return "DIMACS Solver: '%s'"%(self._command) + return "DIMACS Solver: '%s'" % (self._command) def __del__(self): """ @@ -135,7 +135,7 @@ def var(self, decision=None): sage: solver.var() 1 """ - self._var+= 1 + self._var += 1 return self._var def nvars(self): @@ -225,7 +225,7 @@ def write(self, filename=None): headname = self._headname if filename is None else filename head = open(headname, "w") head.truncate(0) - head.write("p cnf %d %d\n"%(self._var,self._lit)) + head.write("p cnf %d %d\n" % (self._var,self._lit)) head.close() tail = self._tail @@ -342,7 +342,7 @@ def render_dimacs(clauses, filename, nlits): """ fh = open(filename, "w") - fh.write("p cnf %d %d\n"%(nlits,len(clauses))) + fh.write("p cnf %d %d\n" % (nlits,len(clauses))) for clause in clauses: if len(clause) == 3 and clause[1] in (True, False) and clause[2] in (True,False,None): lits, is_xor, rhs = clause @@ -351,7 +351,7 @@ def render_dimacs(clauses, filename, nlits): if is_xor: closing = lits[-1] if rhs else -lits[-1] - fh.write("x" + " ".join(map(str, lits[:-1])) + " %d 0\n"%closing) + fh.write("x" + " ".join(map(str, lits[:-1])) + " %d 0\n" % closing) else: fh.write(" ".join(map(str, lits)) + " 0\n") fh.close() @@ -518,7 +518,7 @@ def __call__(self, assumptions=None): if v_lines: L = " ".join(v_lines).split(" ") assert L[-1] == "0", "last digit of solution line must be zero (not {})".format(L[-1]) - return (None,) + tuple(int(e)>0 for e in L[:-1]) + return (None,) + tuple(int(e) > 0 for e in L[:-1]) else: raise ValueError("When parsing the output, no line starts with letter v or s") diff --git a/src/sage/sat/solvers/sat_lp.py b/src/sage/sat/solvers/sat_lp.py index af9d68e98a0..d96ed62b125 100644 --- a/src/sage/sat/solvers/sat_lp.py +++ b/src/sage/sat/solvers/sat_lp.py @@ -53,7 +53,7 @@ def var(self): 1 """ nvars = n = self._LP.number_of_variables() - while nvars==self._LP.number_of_variables(): + while nvars == self._LP.number_of_variables(): n += 1 self._vars[n] # creates the variable if needed return n @@ -101,8 +101,8 @@ def add_clause(self, lits): if 0 in lits: raise ValueError("0 should not appear in the clause: {}".format(lits)) p = self._LP - p.add_constraint(p.sum(self._vars[x] if x>0 else 1-self._vars[-x] for x in lits) - >=1) + p.add_constraint(p.sum(self._vars[x] if x > 0 else 1-self._vars[-x] for x in lits) + >= 1) def __call__(self): """ diff --git a/src/sage/tensor/modules/comp.py b/src/sage/tensor/modules/comp.py index 482324c1b44..e4061826e83 100644 --- a/src/sage/tensor/modules/comp.py +++ b/src/sage/tensor/modules/comp.py @@ -3259,7 +3259,7 @@ def _ordered_indices(self, indices): if indsym_ordered != indsym: # Permutation linking indsym_ordered to indsym: # (the +1 is required to fulfill the convention of Permutation) - perm = [indsym.index(i) +1 for i in indsym_ordered] + perm = [indsym.index(i) + 1 for i in indsym_ordered] #c# Permutation(perm).signature() sign *= Permutation(perm).signature() ind = tuple(ind) diff --git a/src/sage/tensor/modules/free_module_linear_group.py b/src/sage/tensor/modules/free_module_linear_group.py index 36623143617..a58bd3a8a72 100644 --- a/src/sage/tensor/modules/free_module_linear_group.py +++ b/src/sage/tensor/modules/free_module_linear_group.py @@ -433,7 +433,7 @@ def _an_element_(self): self._fmodule.an_element() comp = resu.set_comp() for i in self._fmodule.irange(): - if i%2 == 0: + if i % 2 == 0: comp[[i,i]] = self._fmodule._ring.one() else: comp[[i,i]] = -(self._fmodule._ring.one()) @@ -547,7 +547,7 @@ def _latex_(self): """ from sage.misc.latex import latex - return r"\mathrm{GL}\left("+ latex(self._fmodule)+ r"\right)" + return r"\mathrm{GL}\left(" + latex(self._fmodule) + r"\right)" def base_module(self): r""" diff --git a/src/sage/tensor/modules/free_module_tensor.py b/src/sage/tensor/modules/free_module_tensor.py index 4d84d76b58a..1412638f64a 100644 --- a/src/sage/tensor/modules/free_module_tensor.py +++ b/src/sage/tensor/modules/free_module_tensor.py @@ -1610,7 +1610,7 @@ def __setitem__(self, args, value): elif not isinstance(args[0], (int, Integer, slice)): basis = args[0] args = args[1:] - if len(args)==1: + if len(args) == 1: args = args[0] # to accommodate for [e,:] syntax else: basis = self._fmodule._def_basis diff --git a/src/tox.ini b/src/tox.ini index 5021d0aa691..fea30bea362 100644 --- a/src/tox.ini +++ b/src/tox.ini @@ -127,7 +127,7 @@ description = # W605: invalid escape sequence ‘x’ # See https://pycodestyle.pycqa.org/en/latest/intro.html#error-codes deps = pycodestyle -commands = pycodestyle --select E111,E21,E222,E227,E25,E271,E303,E305,E306,E401,E502,E701,E702,E703,E71,E72,W291,W293,W391,W605 {posargs:{toxinidir}/sage/} +commands = pycodestyle --select E111,E21,E222,E225,E227,E228,E25,E271,E303,E305,E306,E401,E502,E701,E702,E703,E71,E72,W291,W293,W391,W605 {posargs:{toxinidir}/sage/} pycodestyle --select E111,E271,E301,E306,E401,E502,E703,E712,E713,E714,E72,W29,W391,W605, --filename *.pyx {posargs:{toxinidir}/sage/} [pycodestyle] From aaddb607ad4936df2d8c74fffcc55769dad23776 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Sun, 8 Oct 2023 17:51:56 +0200 Subject: [PATCH 055/216] really fix E228 and E225 --- src/sage_docbuild/conf.py | 6 ++-- src/sage_docbuild/ext/multidocs.py | 18 +++++------ src/sage_setup/autogen/giacpy-mkkeywords.py | 30 +++++++++---------- .../autogen/interpreters/specs/python.py | 2 +- src/sage_setup/command/sage_build_ext.py | 2 +- src/sage_setup/run_parallel.py | 10 +++---- 6 files changed, 34 insertions(+), 34 deletions(-) diff --git a/src/sage_docbuild/conf.py b/src/sage_docbuild/conf.py index 0df2760c035..5eca4ed29b0 100644 --- a/src/sage_docbuild/conf.py +++ b/src/sage_docbuild/conf.py @@ -745,7 +745,7 @@ def find_sage_dangling_links(app, env, node, contnode): debug_inf(app, "-- no refdoc in node %s" % node) return None - debug_inf(app, "Searching %s from %s"%(reftarget, doc)) + 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 @@ -803,7 +803,7 @@ def find_sage_dangling_links(app, env, node, contnode): ', '.join(match[0] for match in matches)), node.line) name, obj = matches[0] - debug_inf(app, "++ match = %s %s"%(name, obj)) + debug_inf(app, "++ match = %s %s" % (name, obj)) from docutils import nodes newnode = nodes.reference('', '', internal=True) @@ -812,7 +812,7 @@ def find_sage_dangling_links(app, env, node, contnode): else: newnode['refuri'] = builder.get_relative_uri(node['refdoc'], obj[0]) newnode['refuri'] += '#' + name - debug_inf(app, "++ DONE at URI %s"%(newnode['refuri'])) + debug_inf(app, "++ DONE at URI %s" % (newnode['refuri'])) newnode['reftitle'] = name newnode.append(contnode) return newnode diff --git a/src/sage_docbuild/ext/multidocs.py b/src/sage_docbuild/ext/multidocs.py index 70096178b9f..468ed2c1b86 100644 --- a/src/sage_docbuild/ext/multidocs.py +++ b/src/sage_docbuild/ext/multidocs.py @@ -47,14 +47,14 @@ def merge_environment(app, env): """ logger.info(bold('Merging environment/index files...')) for curdoc in app.env.config.multidocs_subdoc_list: - logger.info(" %s:"%curdoc, nonl=1) + logger.info(" %s:" % curdoc, nonl=1) docenv = get_env(app, curdoc) if docenv is not None: fixpath = lambda path: os.path.join(curdoc, path) todos = docenv.domaindata['todo'].get('todos', dict()) citations = docenv.domaindata['citation'].get('citations', dict()) indexentries = docenv.domaindata['index'].get('entries', dict()) - logger.info(" %s todos, %s index, %s citations"%( + logger.info(" %s todos, %s index, %s citations" % ( sum(len(t) for t in todos.values()), len(indexentries), len(citations) @@ -97,8 +97,8 @@ def merge_environment(app, env): for ind,mod in docenv.domaindata['py']['modules'].items(): newmodules[ind] = ModuleEntry(fixpath(mod.docname), mod.node_id, mod.synopsis, mod.platform, mod.deprecated) env.domaindata['py']['modules'].update(newmodules) - logger.info(", %s modules"%(len(newmodules))) - logger.info('... done (%s todos, %s index, %s citations, %s modules)'%( + logger.info(", %s modules" % (len(newmodules))) + logger.info('... done (%s todos, %s index, %s citations, %s modules)' % ( sum(len(t) for t in env.domaindata['todo']['todos'].values()), len(env.domaindata['index']['entries']), len(env.domaindata['citation']['citations']), @@ -131,12 +131,12 @@ def merge_js_index(app): logger.info(bold('Merging js index files...')) mapping = app.builder.indexer._mapping for curdoc in app.env.config.multidocs_subdoc_list: - logger.info(" %s:"%curdoc, nonl=1) + logger.info(" %s:" % curdoc, nonl=1) fixpath = lambda path: os.path.join(curdoc, path) index = get_js_index(app, curdoc) if index is not None: # merge the mappings - logger.info(" %s js index entries"%(len(index._mapping))) + logger.info(" %s js index entries" % (len(index._mapping))) for (ref, locs) in index._mapping.items(): newmapping = set(map(fixpath, locs)) if ref in mapping: @@ -160,7 +160,7 @@ def merge_js_index(app): dest = os.path.join(app.outdir, "_sources", curdoc) if not os.path.exists(dest): os.symlink(os.path.join("..", curdoc, "_sources"), dest) - logger.info('... done (%s js index entries)'%(len(mapping))) + logger.info('... done (%s js index entries)' % (len(mapping))) logger.info(bold('Writing js search indexes...'), nonl=1) return [] # no extra page to setup @@ -171,7 +171,7 @@ def get_js_index(app, curdoc): """ from sphinx.search import IndexBuilder, languages # FIXME: find the correct lang - sphinx_version=__import__("sphinx").__version__ + sphinx_version = __import__("sphinx").__version__ if (sphinx_version < '1.2'): indexer = IndexBuilder(app.env, 'en', app.config.html_search_options) @@ -260,7 +260,7 @@ def fetch_citation(app: Sphinx, env): return with open(file, 'rb') as f: cache = pickle.load(f) - logger.info("done (%s citations)."%len(cache)) + logger.info("done (%s citations)." % len(cache)) cite = env.domaindata['citation'].get('citations', dict()) for ind, (path, tag, lineno) in cache.items(): if ind not in cite: # don't override local citation diff --git a/src/sage_setup/autogen/giacpy-mkkeywords.py b/src/sage_setup/autogen/giacpy-mkkeywords.py index 5d2acee1b93..c1a277b119c 100644 --- a/src/sage_setup/autogen/giacpy-mkkeywords.py +++ b/src/sage_setup/autogen/giacpy-mkkeywords.py @@ -34,7 +34,7 @@ # usualvars=['x','y','z','t','u','v'] -moremethods=['type','zip'] +moremethods = ['type','zip'] # append seems fixed with current giac. @@ -42,35 +42,35 @@ # provided in giac source archive or installled in share/giac/doc like this: #grep -E '^#' share/giac/doc/aide_cas |sed -e 's/^# //' >aide_cas.txt with open('aide_cas.txt') as f: - mostkeywords=f.read().split() + mostkeywords = f.read().split() -mostkeywordorig=['Airy_Ai', 'Airy_Bi', 'Archive', 'BesselJ', 'BesselY', 'Beta', 'BlockDiagonal', 'Ci', 'Circle', 'Col', 'CopyVar', 'Dirac', 'Ei', 'Factor', 'GF', 'Gamma', 'Heaviside', 'JordanBlock', 'LU', 'LambertW', 'Li', 'Line', 'LineHorz', 'LineTan', 'LineVert', 'Phi', 'Pi', 'Psi', 'QR', 'RandSeed', 'Row', 'SortA', 'SortD', 'UTPC', 'UTPF', 'UTPN', 'UTPT', 'VARS', 'VAS', 'VAS_positive', 'Zeta', '_qe_', 'a2q', 'abcuv', 'about', 'abs', 'abscissa', 'accumulate_head_tail', 'acos', 'acos2asin', 'acos2atan', 'acosh', 'acot', 'acsc', 'acyclic', 'add', 'add_arc', 'add_edge', 'add_vertex', 'additionally', 'adjacency_matrix', 'adjoint_matrix', 'affix', 'algsubs', 'algvar', 'all_trig_solutions', 'allpairs_distance', 'alog10', 'altitude', 'angle', 'angle_radian', 'angleat', 'angleatraw', 'ans', 'antiprism_graph', 'apply', 'approx', 'arc', 'arcLen', 'arccos', 'arccosh', 'arclen', 'arcsin', 'arcsinh', 'arctan', 'arctanh', 'area', 'areaat', 'areaatraw', 'areaplot', 'arg', 'array', 'arrivals', 'articulation_points', 'asin', 'asin2acos', 'asin2atan', 'asinh', 'assign_edge_weights', 'assume', 'at', 'atan', 'atan2acos', 'atan2asin', 'atanh', 'atrig2ln', 'augment', 'auto_correlation', 'autosimplify', 'avance', 'avgRC', 'axes', 'back', 'backward', 'baisse_crayon', 'bandwidth', 'bar_plot', 'bartlett_hann_window', 'barycenter', 'base', 'basis', 'batons', 'bellman_ford', 'bernoulli', 'besselJ', 'besselY', 'betad', 'betad_cdf', 'betad_icdf', 'betavariate', 'bezier', 'bezout_entiers', 'biconnected_components', 'binomial', 'binomial_cdf', 'binomial_icdf', 'bins', 'bipartite', 'bipartite_matching', 'bisection_solver', 'bisector', 'bit_depth', 'bitand', 'bitor', 'bitxor', 'blackman_harris_window', 'blackman_window', 'blockmatrix', 'bohman_window', 'border', 'boxwhisker', 'brent_solver', 'bvpsolve', 'cFactor', 'cSolve', 'cZeros', 'camembert', 'canonical_form', 'canonical_labeling', 'cartesian_product', 'cauchy', 'cauchy_cdf', 'cauchy_icdf', 'cauchyd', 'cauchyd_cdf', 'cauchyd_icdf', 'cdf', 'ceil', 'ceiling', 'center', 'center2interval', 'centered_cube', 'centered_tetrahedron', 'cfactor', 'cfsolve', 'changebase', 'channel_data', 'channels', 'char', 'charpoly', 'chinrem', 'chisquare', 'chisquare_cdf', 'chisquare_icdf', 'chisquared', 'chisquared_cdf', 'chisquared_icdf', 'chisquaret', 'choice', 'cholesky', 'chr', 'chrem', 'chromatic_index', 'chromatic_number', 'chromatic_polynomial', 'circle', 'circumcircle', 'classes', 'clear', 'clique_cover', 'clique_cover_number', 'clique_number', 'clique_stats', 'clustering_coefficient', 'coeff', 'coeffs', 'col', 'colDim', 'colNorm', 'colSwap', 'coldim', 'collect', 'colnorm', 'color', 'colspace', 'colswap', 'comDenom', 'comb', 'combine', 'comment', 'common_perpendicular', 'companion', 'compare', 'complete_binary_tree', 'complete_graph', 'complete_kary_tree', 'complex', 'complex_variables', 'complexroot', 'concat', 'cond', 'condensation', 'cone', 'confrac', 'conic', 'conj', 'conjugate_equation', 'conjugate_gradient', 'connected', 'connected_components', 'cont', 'contains', 'content', 'contourplot', 'contract_edge', 'convert', 'convertir', 'convex', 'convexhull', 'convolution', 'coordinates', 'copy', 'correlation', 'cos', 'cos2sintan', 'cosh', 'cosine_window', 'cot', 'cote', 'count', 'count_eq', 'count_inf', 'count_sup', 'courbe_parametrique', 'courbe_polaire', 'covariance', 'covariance_correlation', 'cpartfrac', 'crationalroot', 'crayon', 'createwav', 'cross', 'crossP', 'cross_correlation', 'cross_point', 'cross_ratio', 'crossproduct', 'csc', 'csolve', 'csv2gen', 'cube', 'cumSum', 'cumsum', 'cumulated_frequencies', 'curl', 'current_sheet', 'curvature', 'curve', 'cyan', 'cycle2perm', 'cycle_graph', 'cycleinv', 'cycles2permu', 'cyclotomic', 'cylinder', 'dash_line', 'dashdot_line', 'dashdotdot_line', 'dayofweek', 'deSolve', 'debut_enregistrement', 'degree', 'degree_sequence', 'delcols', 'delete_arc', 'delete_edge', 'delete_vertex', 'delrows', 'deltalist', 'denom', 'densityplot', 'departures', 'derive', 'deriver', 'desolve', 'dessine_tortue', 'det', 'det_minor', 'developper', 'developper_transcendant', 'dfc', 'dfc2f', 'diag', 'diff', 'digraph', 'dijkstra', 'dim', 'directed', 'discard_edge_attribute', 'discard_graph_attribute', 'discard_vertex_attribute', 'disjoint_union', 'display', 'disque', 'disque_centre', 'distance', 'distance2', 'distanceat', 'distanceatraw', 'divergence', 'divide', 'divis', 'division_point', 'divisors', 'divmod', 'divpc', 'dnewton_solver', 'dodecahedron', 'domain', 'dot', 'dotP', 'dot_paper', 'dotprod', 'draw_arc', 'draw_circle', 'draw_graph', 'draw_line', 'draw_pixel', 'draw_polygon', 'draw_rectangle', 'droit', 'droite_tangente', 'dsolve', 'duration', 'e', 'e2r', 'ecart_type', 'ecart_type_population', 'ecm_factor', 'edge_connectivity', 'edges', 'egcd', 'egv', 'egvl', 'eigVc', 'eigVl', 'eigenvals', 'eigenvalues', 'eigenvectors', 'eigenvects', 'element', 'eliminate', 'ellipse', 'entry', 'envelope', 'epsilon', 'epsilon2zero', 'equal', 'equal2diff', 'equal2list', 'equation', 'equilateral_triangle', 'erf', 'erfc', 'error', 'est_permu', 'euler', 'euler_gamma', 'euler_lagrange', 'eval_level', 'evala', 'evalb', 'evalc', 'evalf', 'evalm', 'even', 'evolute', 'exact', 'exbisector', 'excircle', 'execute', 'exp', 'exp2list', 'exp2pow', 'exp2trig', 'expand', 'expexpand', 'expln', 'exponential', 'exponential_cdf', 'exponential_icdf', 'exponential_regression', 'exponential_regression_plot', 'exponentiald', 'exponentiald_cdf', 'exponentiald_icdf', 'export_graph', 'expovariate', 'expr', 'extend', 'extract_measure', 'extrema', 'ezgcd', 'f2nd', 'fMax', 'fMin', 'fPart', 'faces', 'facteurs_premiers', 'factor', 'factor_xn', 'factorial', 'factoriser', 'factoriser_entier', 'factoriser_sur_C', 'factors', 'fadeev', 'false', 'falsepos_solver', 'fclose', 'fcoeff', 'fdistrib', 'fft', 'fieldplot', 'find', 'find_cycles', 'findhelp', 'fisher', 'fisher_cdf', 'fisher_icdf', 'fisherd', 'fisherd_cdf', 'fisherd_icdf', 'fitdistr', 'flatten', 'float2rational', 'floor', 'flow_polynomial', 'fmod', 'foldl', 'foldr', 'fonction_derivee', 'forward', 'fourier_an', 'fourier_bn', 'fourier_cn', 'fprint', 'frac', 'fracmod', 'frame_2d', 'frequencies', 'frobenius_norm', 'froot', 'fsolve', 'fullparfrac', 'funcplot', 'function_diff', 'fxnd', 'gammad', 'gammad_cdf', 'gammad_icdf', 'gammavariate', 'gauss', 'gauss15', 'gauss_seidel_linsolve', 'gaussian_window', 'gaussjord', 'gaussquad', 'gbasis', 'gbasis_max_pairs', 'gbasis_reinject', 'gbasis_simult_primes', 'gcd', 'gcdex', 'genpoly', 'geometric', 'geometric_cdf', 'geometric_icdf', 'getDenom', 'getKey', 'getNum', 'getType', 'get_edge_attribute', 'get_edge_weight', 'get_graph_attribute', 'get_vertex_attribute', 'girth', 'gl_showaxes', 'grad', 'gramschmidt', 'graph', 'graph_automorphisms', 'graph_charpoly', 'graph_complement', 'graph_diameter', 'graph_equal', 'graph_join', 'graph_power', 'graph_rank', 'graph_spectrum', 'graph_union', 'graph_vertices', 'greduce', 'greedy_color', 'grid_graph', 'groupermu', 'hadamard', 'half_cone', 'half_line', 'halftan', 'halftan_hyp2exp', 'halt', 'hamdist', 'hamming_window', 'hann_poisson_window', 'hann_window', 'harmonic_conjugate', 'harmonic_division', 'has', 'has_arc', 'has_edge', 'hasard', 'head', 'heading', 'heapify', 'heappop', 'heappush', 'hermite', 'hessenberg', 'hessian', 'heugcd', 'hexagon', 'highlight_edges', 'highlight_subgraph', 'highlight_trail', 'highlight_vertex', 'highpass', 'hilbert', 'histogram', 'hold', 'homothety', 'horner', 'hybrid_solver', 'hybridj_solver', 'hybrids_solver', 'hybridsj_solver', 'hyp2exp', 'hyperbola', 'hypercube_graph', 'iPart', 'iabcuv', 'ibasis', 'ibpdv', 'ibpu', 'icdf', 'ichinrem', 'ichrem', 'icomp', 'icontent', 'icosahedron', 'id', 'identity', 'idivis', 'idn', 'iegcd', 'ifactor', 'ifactors', 'igamma', 'igcd', 'igcdex', 'ihermite', 'ilaplace', 'im', 'imag', 'image', 'implicitdiff', 'implicitplot', 'import_graph', 'inString', 'in_ideal', 'incidence_matrix', 'incident_edges', 'incircle', 'increasing_power', 'independence_number', 'indets', 'index', 'induced_subgraph', 'inequationplot', 'inf', 'infinity', 'insert', 'insmod', 'int', 'intDiv', 'integer', 'integrate', 'integrer', 'inter', 'interactive_odeplot', 'interactive_plotode', 'interp', 'interval', 'interval2center', 'interval_graph', 'inv', 'inverse', 'inversion', 'invisible_point', 'invlaplace', 'invztrans', 'iquo', 'iquorem', 'iratrecon', 'irem', 'isPrime', 'is_acyclic', 'is_arborescence', 'is_biconnected', 'is_bipartite', 'is_clique', 'is_collinear', 'is_concyclic', 'is_conjugate', 'is_connected', 'is_coplanar', 'is_cospherical', 'is_cut_set', 'is_cycle', 'is_directed', 'is_element', 'is_equilateral', 'is_eulerian', 'is_forest', 'is_graphic_sequence', 'is_hamiltonian', 'is_harmonic', 'is_harmonic_circle_bundle', 'is_harmonic_line_bundle', 'is_inside', 'is_integer_graph', 'is_isomorphic', 'is_isosceles', 'is_network', 'is_orthogonal', 'is_parallel', 'is_parallelogram', 'is_permu', 'is_perpendicular', 'is_planar', 'is_prime', 'is_pseudoprime', 'is_rectangle', 'is_regular', 'is_rhombus', 'is_square', 'is_strongly_connected', 'is_strongly_regular', 'is_tournament', 'is_tree', 'is_triconnected', 'is_two_edge_connected', 'is_vertex_colorable', 'is_weighted', 'ismith', 'isobarycenter', 'isom', 'isomorphic_copy', 'isopolygon', 'isosceles_triangle', 'isprime', 'ithprime', 'jacobi_equation', 'jacobi_linsolve', 'jacobi_symbol', 'jordan', 'kde', 'keep_pivot', 'ker', 'kernel', 'kernel_density', 'kneser_graph', 'kolmogorovd', 'kolmogorovt', 'kovacicsols', 'kspaths', 'l1norm', 'l2norm', 'lagrange', 'laguerre', 'laplace', 'laplacian', 'laplacian_matrix', 'latex', 'lcf_graph', 'lcm', 'lcoeff', 'ldegree', 'left', 'left_rectangle', 'legend', 'legendre', 'legendre_symbol', 'length', 'lgcd', 'lhs', 'ligne_chapeau_carre', 'ligne_chapeau_plat', 'ligne_chapeau_rond', 'ligne_polygonale', 'ligne_polygonale_pointee', 'ligne_tiret', 'ligne_tiret_point', 'ligne_tiret_pointpoint', 'ligne_trait_plein', 'limit', 'limite', 'lin', 'line', 'line_graph', 'line_inter', 'line_paper', 'line_segments', 'linear_interpolate', 'linear_regression', 'linear_regression_plot', 'lineariser', 'lineariser_trigo', 'linfnorm', 'linsolve', 'linspace', 'lis_phrase', 'list2exp', 'list2mat', 'list_edge_attributes', 'list_graph_attributes', 'list_vertex_attributes', 'listplot', 'lll', 'ln', 'lname', 'lncollect', 'lnexpand', 'locus', 'log', 'log10', 'logarithmic_regression', 'logarithmic_regression_plot', 'logb', 'logistic_regression', 'logistic_regression_plot', 'lower', 'lowest_common_ancestor', 'lowpass', 'lp_assume', 'lp_bestprojection', 'lp_binary', 'lp_binaryvariables', 'lp_breadthfirst', 'lp_depthfirst', 'lp_depthlimit', 'lp_firstfractional', 'lp_gaptolerance', 'lp_hybrid', 'lp_initialpoint', 'lp_integer', 'lp_integertolerance', 'lp_integervariables', 'lp_interiorpoint', 'lp_iterationlimit', 'lp_lastfractional', 'lp_maxcuts', 'lp_maximize', 'lp_method', 'lp_mostfractional', 'lp_nodelimit', 'lp_nodeselect', 'lp_nonnegative', 'lp_nonnegint', 'lp_pseudocost', 'lp_simplex', 'lp_timelimit', 'lp_variables', 'lp_varselect', 'lp_verbose', 'lpsolve', 'lsmod', 'lsq', 'lu', 'lvar', 'mRow', 'mRowAdd', 'magenta', 'make_directed', 'make_weighted', 'makelist', 'makemat', 'makesuite', 'makevector', 'map', 'maple2mupad', 'maple2xcas', 'maple_ifactors', 'maple_mode', 'markov', 'mat2list', 'mathml', 'matpow', 'matrix', 'matrix_norm', 'max', 'maxflow', 'maximal_independent_set', 'maximize', 'maximum_clique', 'maximum_degree', 'maximum_independent_set', 'maximum_matching', 'maxnorm', 'mean', 'median', 'median_line', 'member', 'mgf', 'mid', 'middle_point', 'midpoint', 'min', 'minimal_edge_coloring', 'minimal_spanning_tree', 'minimal_vertex_coloring', 'minimax', 'minimize', 'minimum_cut', 'minimum_degree', 'mkisom', 'mksa', 'modgcd', 'mods', 'monotonic', 'montre_tortue', 'moustache', 'moving_average', 'moyal', 'moyenne', 'mul', 'mult_c_conjugate', 'mult_conjugate', 'multinomial', 'multiplier_conjugue', 'multiplier_conjugue_complexe', 'multiply', 'mupad2maple', 'mupad2xcas', 'mycielski', 'nCr', 'nDeriv', 'nInt', 'nPr', 'nSolve', 'ncols', 'negbinomial', 'negbinomial_cdf', 'negbinomial_icdf', 'neighbors', 'network_transitivity', 'newList', 'newMat', 'newton', 'newton_solver', 'newtonj_solver', 'nextperm', 'nextprime', 'nlpsolve', 'nodisp', 'non_recursive_normal', 'nop', 'nops', 'norm', 'normal', 'normal_cdf', 'normal_icdf', 'normald', 'normald_cdf', 'normald_icdf', 'normalize', 'normalt', 'normalvariate', 'nprimes', 'nrows', 'nuage_points', 'nullspace', 'number_of_edges', 'number_of_spanning_trees', 'number_of_triangles', 'number_of_vertices', 'numer', 'octahedron', 'odd', 'odd_girth', 'odd_graph', 'odeplot', 'odesolve', 'op', 'open_polygon', 'ord', 'order', 'order_size', 'ordinate', 'orthocenter', 'orthogonal', 'osculating_circle', 'p1oc2', 'p1op2', 'pa2b2', 'pade', 'parabola', 'parallel', 'parallelepiped', 'parallelogram', 'parameq', 'parameter', 'paramplot', 'parfrac', 'pari', 'part', 'partfrac', 'parzen_window', 'pas_de_cote', 'path_graph', 'pcar', 'pcar_hessenberg', 'pcoef', 'pcoeff', 'pencolor', 'pendown', 'penup', 'perimeter', 'perimeterat', 'perimeteratraw', 'periodic', 'perm', 'perminv', 'permu2cycles', 'permu2mat', 'permuorder', 'permute_vertices', 'perpen_bisector', 'perpendicular', 'petersen_graph', 'peval', 'pi', 'piecewise', 'pivot', 'pixoff', 'pixon', 'planar', 'plane', 'plane_dual', 'playsnd', 'plex', 'plot', 'plot3d', 'plotarea', 'plotcdf', 'plotcontour', 'plotdensity', 'plotfield', 'plotfunc', 'plotimplicit', 'plotinequation', 'plotlist', 'plotode', 'plotparam', 'plotpolar', 'plotproba', 'plotseq', 'plotspectrum', 'plotwav', 'plus_point', 'pmin', 'point', 'point2d', 'point3d', 'poisson', 'poisson_cdf', 'poisson_icdf', 'poisson_window', 'polar', 'polar_coordinates', 'polar_point', 'polarplot', 'pole', 'poly2symb', 'polyEval', 'polygon', 'polygone_rempli', 'polygonplot', 'polygonscatterplot', 'polyhedron', 'polynom', 'polynomial_regression', 'polynomial_regression_plot', 'position', 'poslbdLMQ', 'posubLMQ', 'potential', 'pow2exp', 'power_regression', 'power_regression_plot', 'powermod', 'powerpc', 'powexpand', 'powmod', 'prepend', 'preval', 'prevperm', 'prevprime', 'primpart', 'printf', 'prism', 'prism_graph', 'product', 'projection', 'proot', 'propFrac', 'propfrac', 'psrgcd', 'ptayl', 'purge', 'pwd', 'pyramid', 'python_compat', 'q2a', 'qr', 'quadric', 'quadrilateral', 'quantile', 'quartile1', 'quartile3', 'quartiles', 'quest', 'quo', 'quorem', 'quote', 'r2e', 'radical_axis', 'radius', 'ramene', 'rand', 'randMat', 'randNorm', 'randPoly', 'randbetad', 'randbinomial', 'randchisquare', 'randexp', 'randfisher', 'randgammad', 'randgeometric', 'randint', 'randmarkov', 'randmatrix', 'randmultinomial', 'randnorm', 'random', 'random_bipartite_graph', 'random_digraph', 'random_graph', 'random_network', 'random_planar_graph', 'random_regular_graph', 'random_sequence_graph', 'random_tournament', 'random_tree', 'random_variable', 'randperm', 'randpoisson', 'randpoly', 'randseed', 'randstudent', 'randvar', 'randvector', 'randweibulld', 'rank', 'ranm', 'ranv', 'rassembler_trigo', 'rat_jordan', 'rational', 'rationalroot', 'ratnormal', 'rcl', 'rdiv', 're', 'read', 'readrgb', 'readwav', 'real', 'realroot', 'reciprocation', 'rectangle', 'rectangle_droit', 'rectangle_gauche', 'rectangle_plein', 'rectangular_coordinates', 'recule', 'red', 'reduced_conic', 'reduced_quadric', 'ref', 'reflection', 'regroup', 'relabel_vertices', 'reliability_polynomial', 'rem', 'remain', 'remove', 'reorder', 'resample', 'residue', 'resoudre', 'resoudre_dans_C', 'resoudre_systeme_lineaire', 'resultant', 'reverse', 'reverse_graph', 'reverse_rsolve', 'revert', 'revlex', 'revlist', 'rgb', 'rhombus', 'rhombus_point', 'rhs', 'riemann_window', 'right', 'right_rectangle', 'right_triangle', 'risch', 'rm_a_z', 'rm_all_vars', 'rmbreakpoint', 'rmmod', 'rmwatch', 'romberg', 'rombergm', 'rombergt', 'rond', 'root', 'rootof', 'roots', 'rotate', 'rotation', 'round', 'row', 'rowAdd', 'rowDim', 'rowNorm', 'rowSwap', 'rowdim', 'rownorm', 'rowspace', 'rowswap', 'rref', 'rsolve', 'same', 'sample', 'samplerate', 'sans_factoriser', 'saute', 'scalarProduct', 'scalar_product', 'scatterplot', 'schur', 'sec', 'secant_solver', 'segment', 'seidel_spectrum', 'seidel_switch', 'select', 'semi_augment', 'seq', 'seqplot', 'seqsolve', 'sequence_graph', 'series', 'set_edge_attribute', 'set_edge_weight', 'set_graph_attribute', 'set_pixel', 'set_vertex_attribute', 'set_vertex_positions', 'shift', 'shift_phase', 'shortest_path', 'show_pixels', 'shuffle', 'sierpinski_graph', 'sign', 'signature', 'signe', 'similarity', 'simp2', 'simplex_reduce', 'simplifier', 'simplify', 'simpson', 'simult', 'sin', 'sin2costan', 'sincos', 'single_inter', 'sinh', 'sizes', 'slope', 'slopeat', 'slopeatraw', 'smith', 'smod', 'snedecor', 'snedecor_cdf', 'snedecor_icdf', 'snedecord', 'snedecord_cdf', 'snedecord_icdf', 'solid_line', 'solve', 'somme', 'sommet', 'sort', 'sorta', 'sortd', 'sorted', 'soundsec', 'spanning_tree', 'sphere', 'spline', 'split', 'spring', 'sq', 'sqrfree', 'sqrt', 'square', 'square_point', 'srand', 'sst', 'sst_in', 'st_ordering', 'star_graph', 'star_point', 'start', 'stdDev', 'stddev', 'stddevp', 'steffenson_solver', 'stereo2mono', 'str', 'strongly_connected_components', 'student', 'student_cdf', 'student_icdf', 'studentd', 'studentt', 'sturm', 'sturmab', 'sturmseq', 'style', 'subMat', 'subdivide_edges', 'subgraph', 'subs', 'subsop', 'subst', 'substituer', 'subtype', 'sum', 'sum_riemann', 'suppress', 'surd', 'svd', 'swapcol', 'swaprow', 'switch_axes', 'sylvester', 'symb2poly', 'symbol', 'syst2mat', 'tCollect', 'tExpand', 'table', 'tablefunc', 'tableseq', 'tabvar', 'tail', 'tan', 'tan2cossin2', 'tan2sincos', 'tan2sincos2', 'tangent', 'tangente', 'tanh', 'taux_accroissement', 'taylor', 'tchebyshev1', 'tchebyshev2', 'tcoeff', 'tcollect', 'tdeg', 'tensor_product', 'tetrahedron', 'texpand', 'thickness', 'threshold', 'throw', 'title', 'titre', 'tlin', 'tonnetz', 'topologic_sort', 'topological_sort', 'torus_grid_graph', 'total_degree', 'tourne_droite', 'tourne_gauche', 'tpsolve', 'trace', 'trail', 'trail2edges', 'trames', 'tran', 'transitive_closure', 'translation', 'transpose', 'trapeze', 'trapezoid', 'traveling_salesman', 'tree', 'tree_height', 'triangle', 'triangle_paper', 'triangle_plein', 'triangle_point', 'triangle_window', 'trig2exp', 'trigcos', 'trigexpand', 'triginterp', 'trigsimplify', 'trigsin', 'trigtan', 'trn', 'true', 'trunc', 'truncate', 'truncate_graph', 'tsimplify', 'tuer', 'tukey_window', 'tutte_polynomial', 'two_edge_connected_components', 'ufactor', 'ugamma', 'unapply', 'unarchive', 'underlying_graph', 'unfactored', 'uniform', 'uniform_cdf', 'uniform_icdf', 'uniformd', 'uniformd_cdf', 'uniformd_icdf', 'unitV', 'unquote', 'upper', 'user_operator', 'usimplify', 'valuation', 'vandermonde', 'variables_are_files', 'variance', 'version', 'vertex_connectivity', 'vertex_degree', 'vertex_distance', 'vertex_in_degree', 'vertex_out_degree', 'vertices', 'vertices_abc', 'vertices_abca', 'vpotential', 'web_graph', 'weibull', 'weibull_cdf', 'weibull_icdf', 'weibulld', 'weibulld_cdf', 'weibulld_icdf', 'weibullvariate', 'weight_matrix', 'weighted', 'weights', 'welch_window', 'wheel_graph', 'widget_size', 'wilcoxonp', 'wilcoxons', 'wilcoxont', 'with_sqrt', 'writergb', 'writewav', 'xcas_mode', 'xyztrange', 'zeros', 'ztrans'] +mostkeywordorig = ['Airy_Ai', 'Airy_Bi', 'Archive', 'BesselJ', 'BesselY', 'Beta', 'BlockDiagonal', 'Ci', 'Circle', 'Col', 'CopyVar', 'Dirac', 'Ei', 'Factor', 'GF', 'Gamma', 'Heaviside', 'JordanBlock', 'LU', 'LambertW', 'Li', 'Line', 'LineHorz', 'LineTan', 'LineVert', 'Phi', 'Pi', 'Psi', 'QR', 'RandSeed', 'Row', 'SortA', 'SortD', 'UTPC', 'UTPF', 'UTPN', 'UTPT', 'VARS', 'VAS', 'VAS_positive', 'Zeta', '_qe_', 'a2q', 'abcuv', 'about', 'abs', 'abscissa', 'accumulate_head_tail', 'acos', 'acos2asin', 'acos2atan', 'acosh', 'acot', 'acsc', 'acyclic', 'add', 'add_arc', 'add_edge', 'add_vertex', 'additionally', 'adjacency_matrix', 'adjoint_matrix', 'affix', 'algsubs', 'algvar', 'all_trig_solutions', 'allpairs_distance', 'alog10', 'altitude', 'angle', 'angle_radian', 'angleat', 'angleatraw', 'ans', 'antiprism_graph', 'apply', 'approx', 'arc', 'arcLen', 'arccos', 'arccosh', 'arclen', 'arcsin', 'arcsinh', 'arctan', 'arctanh', 'area', 'areaat', 'areaatraw', 'areaplot', 'arg', 'array', 'arrivals', 'articulation_points', 'asin', 'asin2acos', 'asin2atan', 'asinh', 'assign_edge_weights', 'assume', 'at', 'atan', 'atan2acos', 'atan2asin', 'atanh', 'atrig2ln', 'augment', 'auto_correlation', 'autosimplify', 'avance', 'avgRC', 'axes', 'back', 'backward', 'baisse_crayon', 'bandwidth', 'bar_plot', 'bartlett_hann_window', 'barycenter', 'base', 'basis', 'batons', 'bellman_ford', 'bernoulli', 'besselJ', 'besselY', 'betad', 'betad_cdf', 'betad_icdf', 'betavariate', 'bezier', 'bezout_entiers', 'biconnected_components', 'binomial', 'binomial_cdf', 'binomial_icdf', 'bins', 'bipartite', 'bipartite_matching', 'bisection_solver', 'bisector', 'bit_depth', 'bitand', 'bitor', 'bitxor', 'blackman_harris_window', 'blackman_window', 'blockmatrix', 'bohman_window', 'border', 'boxwhisker', 'brent_solver', 'bvpsolve', 'cFactor', 'cSolve', 'cZeros', 'camembert', 'canonical_form', 'canonical_labeling', 'cartesian_product', 'cauchy', 'cauchy_cdf', 'cauchy_icdf', 'cauchyd', 'cauchyd_cdf', 'cauchyd_icdf', 'cdf', 'ceil', 'ceiling', 'center', 'center2interval', 'centered_cube', 'centered_tetrahedron', 'cfactor', 'cfsolve', 'changebase', 'channel_data', 'channels', 'char', 'charpoly', 'chinrem', 'chisquare', 'chisquare_cdf', 'chisquare_icdf', 'chisquared', 'chisquared_cdf', 'chisquared_icdf', 'chisquaret', 'choice', 'cholesky', 'chr', 'chrem', 'chromatic_index', 'chromatic_number', 'chromatic_polynomial', 'circle', 'circumcircle', 'classes', 'clear', 'clique_cover', 'clique_cover_number', 'clique_number', 'clique_stats', 'clustering_coefficient', 'coeff', 'coeffs', 'col', 'colDim', 'colNorm', 'colSwap', 'coldim', 'collect', 'colnorm', 'color', 'colspace', 'colswap', 'comDenom', 'comb', 'combine', 'comment', 'common_perpendicular', 'companion', 'compare', 'complete_binary_tree', 'complete_graph', 'complete_kary_tree', 'complex', 'complex_variables', 'complexroot', 'concat', 'cond', 'condensation', 'cone', 'confrac', 'conic', 'conj', 'conjugate_equation', 'conjugate_gradient', 'connected', 'connected_components', 'cont', 'contains', 'content', 'contourplot', 'contract_edge', 'convert', 'convertir', 'convex', 'convexhull', 'convolution', 'coordinates', 'copy', 'correlation', 'cos', 'cos2sintan', 'cosh', 'cosine_window', 'cot', 'cote', 'count', 'count_eq', 'count_inf', 'count_sup', 'courbe_parametrique', 'courbe_polaire', 'covariance', 'covariance_correlation', 'cpartfrac', 'crationalroot', 'crayon', 'createwav', 'cross', 'crossP', 'cross_correlation', 'cross_point', 'cross_ratio', 'crossproduct', 'csc', 'csolve', 'csv2gen', 'cube', 'cumSum', 'cumsum', 'cumulated_frequencies', 'curl', 'current_sheet', 'curvature', 'curve', 'cyan', 'cycle2perm', 'cycle_graph', 'cycleinv', 'cycles2permu', 'cyclotomic', 'cylinder', 'dash_line', 'dashdot_line', 'dashdotdot_line', 'dayofweek', 'deSolve', 'debut_enregistrement', 'degree', 'degree_sequence', 'delcols', 'delete_arc', 'delete_edge', 'delete_vertex', 'delrows', 'deltalist', 'denom', 'densityplot', 'departures', 'derive', 'deriver', 'desolve', 'dessine_tortue', 'det', 'det_minor', 'developper', 'developper_transcendant', 'dfc', 'dfc2f', 'diag', 'diff', 'digraph', 'dijkstra', 'dim', 'directed', 'discard_edge_attribute', 'discard_graph_attribute', 'discard_vertex_attribute', 'disjoint_union', 'display', 'disque', 'disque_centre', 'distance', 'distance2', 'distanceat', 'distanceatraw', 'divergence', 'divide', 'divis', 'division_point', 'divisors', 'divmod', 'divpc', 'dnewton_solver', 'dodecahedron', 'domain', 'dot', 'dotP', 'dot_paper', 'dotprod', 'draw_arc', 'draw_circle', 'draw_graph', 'draw_line', 'draw_pixel', 'draw_polygon', 'draw_rectangle', 'droit', 'droite_tangente', 'dsolve', 'duration', 'e', 'e2r', 'ecart_type', 'ecart_type_population', 'ecm_factor', 'edge_connectivity', 'edges', 'egcd', 'egv', 'egvl', 'eigVc', 'eigVl', 'eigenvals', 'eigenvalues', 'eigenvectors', 'eigenvects', 'element', 'eliminate', 'ellipse', 'entry', 'envelope', 'epsilon', 'epsilon2zero', 'equal', 'equal2diff', 'equal2list', 'equation', 'equilateral_triangle', 'erf', 'erfc', 'error', 'est_permu', 'euler', 'euler_gamma', 'euler_lagrange', 'eval_level', 'evala', 'evalb', 'evalc', 'evalf', 'evalm', 'even', 'evolute', 'exact', 'exbisector', 'excircle', 'execute', 'exp', 'exp2list', 'exp2pow', 'exp2trig', 'expand', 'expexpand', 'expln', 'exponential', 'exponential_cdf', 'exponential_icdf', 'exponential_regression', 'exponential_regression_plot', 'exponentiald', 'exponentiald_cdf', 'exponentiald_icdf', 'export_graph', 'expovariate', 'expr', 'extend', 'extract_measure', 'extrema', 'ezgcd', 'f2nd', 'fMax', 'fMin', 'fPart', 'faces', 'facteurs_premiers', 'factor', 'factor_xn', 'factorial', 'factoriser', 'factoriser_entier', 'factoriser_sur_C', 'factors', 'fadeev', 'false', 'falsepos_solver', 'fclose', 'fcoeff', 'fdistrib', 'fft', 'fieldplot', 'find', 'find_cycles', 'findhelp', 'fisher', 'fisher_cdf', 'fisher_icdf', 'fisherd', 'fisherd_cdf', 'fisherd_icdf', 'fitdistr', 'flatten', 'float2rational', 'floor', 'flow_polynomial', 'fmod', 'foldl', 'foldr', 'fonction_derivee', 'forward', 'fourier_an', 'fourier_bn', 'fourier_cn', 'fprint', 'frac', 'fracmod', 'frame_2d', 'frequencies', 'frobenius_norm', 'froot', 'fsolve', 'fullparfrac', 'funcplot', 'function_diff', 'fxnd', 'gammad', 'gammad_cdf', 'gammad_icdf', 'gammavariate', 'gauss', 'gauss15', 'gauss_seidel_linsolve', 'gaussian_window', 'gaussjord', 'gaussquad', 'gbasis', 'gbasis_max_pairs', 'gbasis_reinject', 'gbasis_simult_primes', 'gcd', 'gcdex', 'genpoly', 'geometric', 'geometric_cdf', 'geometric_icdf', 'getDenom', 'getKey', 'getNum', 'getType', 'get_edge_attribute', 'get_edge_weight', 'get_graph_attribute', 'get_vertex_attribute', 'girth', 'gl_showaxes', 'grad', 'gramschmidt', 'graph', 'graph_automorphisms', 'graph_charpoly', 'graph_complement', 'graph_diameter', 'graph_equal', 'graph_join', 'graph_power', 'graph_rank', 'graph_spectrum', 'graph_union', 'graph_vertices', 'greduce', 'greedy_color', 'grid_graph', 'groupermu', 'hadamard', 'half_cone', 'half_line', 'halftan', 'halftan_hyp2exp', 'halt', 'hamdist', 'hamming_window', 'hann_poisson_window', 'hann_window', 'harmonic_conjugate', 'harmonic_division', 'has', 'has_arc', 'has_edge', 'hasard', 'head', 'heading', 'heapify', 'heappop', 'heappush', 'hermite', 'hessenberg', 'hessian', 'heugcd', 'hexagon', 'highlight_edges', 'highlight_subgraph', 'highlight_trail', 'highlight_vertex', 'highpass', 'hilbert', 'histogram', 'hold', 'homothety', 'horner', 'hybrid_solver', 'hybridj_solver', 'hybrids_solver', 'hybridsj_solver', 'hyp2exp', 'hyperbola', 'hypercube_graph', 'iPart', 'iabcuv', 'ibasis', 'ibpdv', 'ibpu', 'icdf', 'ichinrem', 'ichrem', 'icomp', 'icontent', 'icosahedron', 'id', 'identity', 'idivis', 'idn', 'iegcd', 'ifactor', 'ifactors', 'igamma', 'igcd', 'igcdex', 'ihermite', 'ilaplace', 'im', 'imag', 'image', 'implicitdiff', 'implicitplot', 'import_graph', 'inString', 'in_ideal', 'incidence_matrix', 'incident_edges', 'incircle', 'increasing_power', 'independence_number', 'indets', 'index', 'induced_subgraph', 'inequationplot', 'inf', 'infinity', 'insert', 'insmod', 'int', 'intDiv', 'integer', 'integrate', 'integrer', 'inter', 'interactive_odeplot', 'interactive_plotode', 'interp', 'interval', 'interval2center', 'interval_graph', 'inv', 'inverse', 'inversion', 'invisible_point', 'invlaplace', 'invztrans', 'iquo', 'iquorem', 'iratrecon', 'irem', 'isPrime', 'is_acyclic', 'is_arborescence', 'is_biconnected', 'is_bipartite', 'is_clique', 'is_collinear', 'is_concyclic', 'is_conjugate', 'is_connected', 'is_coplanar', 'is_cospherical', 'is_cut_set', 'is_cycle', 'is_directed', 'is_element', 'is_equilateral', 'is_eulerian', 'is_forest', 'is_graphic_sequence', 'is_hamiltonian', 'is_harmonic', 'is_harmonic_circle_bundle', 'is_harmonic_line_bundle', 'is_inside', 'is_integer_graph', 'is_isomorphic', 'is_isosceles', 'is_network', 'is_orthogonal', 'is_parallel', 'is_parallelogram', 'is_permu', 'is_perpendicular', 'is_planar', 'is_prime', 'is_pseudoprime', 'is_rectangle', 'is_regular', 'is_rhombus', 'is_square', 'is_strongly_connected', 'is_strongly_regular', 'is_tournament', 'is_tree', 'is_triconnected', 'is_two_edge_connected', 'is_vertex_colorable', 'is_weighted', 'ismith', 'isobarycenter', 'isom', 'isomorphic_copy', 'isopolygon', 'isosceles_triangle', 'isprime', 'ithprime', 'jacobi_equation', 'jacobi_linsolve', 'jacobi_symbol', 'jordan', 'kde', 'keep_pivot', 'ker', 'kernel', 'kernel_density', 'kneser_graph', 'kolmogorovd', 'kolmogorovt', 'kovacicsols', 'kspaths', 'l1norm', 'l2norm', 'lagrange', 'laguerre', 'laplace', 'laplacian', 'laplacian_matrix', 'latex', 'lcf_graph', 'lcm', 'lcoeff', 'ldegree', 'left', 'left_rectangle', 'legend', 'legendre', 'legendre_symbol', 'length', 'lgcd', 'lhs', 'ligne_chapeau_carre', 'ligne_chapeau_plat', 'ligne_chapeau_rond', 'ligne_polygonale', 'ligne_polygonale_pointee', 'ligne_tiret', 'ligne_tiret_point', 'ligne_tiret_pointpoint', 'ligne_trait_plein', 'limit', 'limite', 'lin', 'line', 'line_graph', 'line_inter', 'line_paper', 'line_segments', 'linear_interpolate', 'linear_regression', 'linear_regression_plot', 'lineariser', 'lineariser_trigo', 'linfnorm', 'linsolve', 'linspace', 'lis_phrase', 'list2exp', 'list2mat', 'list_edge_attributes', 'list_graph_attributes', 'list_vertex_attributes', 'listplot', 'lll', 'ln', 'lname', 'lncollect', 'lnexpand', 'locus', 'log', 'log10', 'logarithmic_regression', 'logarithmic_regression_plot', 'logb', 'logistic_regression', 'logistic_regression_plot', 'lower', 'lowest_common_ancestor', 'lowpass', 'lp_assume', 'lp_bestprojection', 'lp_binary', 'lp_binaryvariables', 'lp_breadthfirst', 'lp_depthfirst', 'lp_depthlimit', 'lp_firstfractional', 'lp_gaptolerance', 'lp_hybrid', 'lp_initialpoint', 'lp_integer', 'lp_integertolerance', 'lp_integervariables', 'lp_interiorpoint', 'lp_iterationlimit', 'lp_lastfractional', 'lp_maxcuts', 'lp_maximize', 'lp_method', 'lp_mostfractional', 'lp_nodelimit', 'lp_nodeselect', 'lp_nonnegative', 'lp_nonnegint', 'lp_pseudocost', 'lp_simplex', 'lp_timelimit', 'lp_variables', 'lp_varselect', 'lp_verbose', 'lpsolve', 'lsmod', 'lsq', 'lu', 'lvar', 'mRow', 'mRowAdd', 'magenta', 'make_directed', 'make_weighted', 'makelist', 'makemat', 'makesuite', 'makevector', 'map', 'maple2mupad', 'maple2xcas', 'maple_ifactors', 'maple_mode', 'markov', 'mat2list', 'mathml', 'matpow', 'matrix', 'matrix_norm', 'max', 'maxflow', 'maximal_independent_set', 'maximize', 'maximum_clique', 'maximum_degree', 'maximum_independent_set', 'maximum_matching', 'maxnorm', 'mean', 'median', 'median_line', 'member', 'mgf', 'mid', 'middle_point', 'midpoint', 'min', 'minimal_edge_coloring', 'minimal_spanning_tree', 'minimal_vertex_coloring', 'minimax', 'minimize', 'minimum_cut', 'minimum_degree', 'mkisom', 'mksa', 'modgcd', 'mods', 'monotonic', 'montre_tortue', 'moustache', 'moving_average', 'moyal', 'moyenne', 'mul', 'mult_c_conjugate', 'mult_conjugate', 'multinomial', 'multiplier_conjugue', 'multiplier_conjugue_complexe', 'multiply', 'mupad2maple', 'mupad2xcas', 'mycielski', 'nCr', 'nDeriv', 'nInt', 'nPr', 'nSolve', 'ncols', 'negbinomial', 'negbinomial_cdf', 'negbinomial_icdf', 'neighbors', 'network_transitivity', 'newList', 'newMat', 'newton', 'newton_solver', 'newtonj_solver', 'nextperm', 'nextprime', 'nlpsolve', 'nodisp', 'non_recursive_normal', 'nop', 'nops', 'norm', 'normal', 'normal_cdf', 'normal_icdf', 'normald', 'normald_cdf', 'normald_icdf', 'normalize', 'normalt', 'normalvariate', 'nprimes', 'nrows', 'nuage_points', 'nullspace', 'number_of_edges', 'number_of_spanning_trees', 'number_of_triangles', 'number_of_vertices', 'numer', 'octahedron', 'odd', 'odd_girth', 'odd_graph', 'odeplot', 'odesolve', 'op', 'open_polygon', 'ord', 'order', 'order_size', 'ordinate', 'orthocenter', 'orthogonal', 'osculating_circle', 'p1oc2', 'p1op2', 'pa2b2', 'pade', 'parabola', 'parallel', 'parallelepiped', 'parallelogram', 'parameq', 'parameter', 'paramplot', 'parfrac', 'pari', 'part', 'partfrac', 'parzen_window', 'pas_de_cote', 'path_graph', 'pcar', 'pcar_hessenberg', 'pcoef', 'pcoeff', 'pencolor', 'pendown', 'penup', 'perimeter', 'perimeterat', 'perimeteratraw', 'periodic', 'perm', 'perminv', 'permu2cycles', 'permu2mat', 'permuorder', 'permute_vertices', 'perpen_bisector', 'perpendicular', 'petersen_graph', 'peval', 'pi', 'piecewise', 'pivot', 'pixoff', 'pixon', 'planar', 'plane', 'plane_dual', 'playsnd', 'plex', 'plot', 'plot3d', 'plotarea', 'plotcdf', 'plotcontour', 'plotdensity', 'plotfield', 'plotfunc', 'plotimplicit', 'plotinequation', 'plotlist', 'plotode', 'plotparam', 'plotpolar', 'plotproba', 'plotseq', 'plotspectrum', 'plotwav', 'plus_point', 'pmin', 'point', 'point2d', 'point3d', 'poisson', 'poisson_cdf', 'poisson_icdf', 'poisson_window', 'polar', 'polar_coordinates', 'polar_point', 'polarplot', 'pole', 'poly2symb', 'polyEval', 'polygon', 'polygone_rempli', 'polygonplot', 'polygonscatterplot', 'polyhedron', 'polynom', 'polynomial_regression', 'polynomial_regression_plot', 'position', 'poslbdLMQ', 'posubLMQ', 'potential', 'pow2exp', 'power_regression', 'power_regression_plot', 'powermod', 'powerpc', 'powexpand', 'powmod', 'prepend', 'preval', 'prevperm', 'prevprime', 'primpart', 'printf', 'prism', 'prism_graph', 'product', 'projection', 'proot', 'propFrac', 'propfrac', 'psrgcd', 'ptayl', 'purge', 'pwd', 'pyramid', 'python_compat', 'q2a', 'qr', 'quadric', 'quadrilateral', 'quantile', 'quartile1', 'quartile3', 'quartiles', 'quest', 'quo', 'quorem', 'quote', 'r2e', 'radical_axis', 'radius', 'ramene', 'rand', 'randMat', 'randNorm', 'randPoly', 'randbetad', 'randbinomial', 'randchisquare', 'randexp', 'randfisher', 'randgammad', 'randgeometric', 'randint', 'randmarkov', 'randmatrix', 'randmultinomial', 'randnorm', 'random', 'random_bipartite_graph', 'random_digraph', 'random_graph', 'random_network', 'random_planar_graph', 'random_regular_graph', 'random_sequence_graph', 'random_tournament', 'random_tree', 'random_variable', 'randperm', 'randpoisson', 'randpoly', 'randseed', 'randstudent', 'randvar', 'randvector', 'randweibulld', 'rank', 'ranm', 'ranv', 'rassembler_trigo', 'rat_jordan', 'rational', 'rationalroot', 'ratnormal', 'rcl', 'rdiv', 're', 'read', 'readrgb', 'readwav', 'real', 'realroot', 'reciprocation', 'rectangle', 'rectangle_droit', 'rectangle_gauche', 'rectangle_plein', 'rectangular_coordinates', 'recule', 'red', 'reduced_conic', 'reduced_quadric', 'ref', 'reflection', 'regroup', 'relabel_vertices', 'reliability_polynomial', 'rem', 'remain', 'remove', 'reorder', 'resample', 'residue', 'resoudre', 'resoudre_dans_C', 'resoudre_systeme_lineaire', 'resultant', 'reverse', 'reverse_graph', 'reverse_rsolve', 'revert', 'revlex', 'revlist', 'rgb', 'rhombus', 'rhombus_point', 'rhs', 'riemann_window', 'right', 'right_rectangle', 'right_triangle', 'risch', 'rm_a_z', 'rm_all_vars', 'rmbreakpoint', 'rmmod', 'rmwatch', 'romberg', 'rombergm', 'rombergt', 'rond', 'root', 'rootof', 'roots', 'rotate', 'rotation', 'round', 'row', 'rowAdd', 'rowDim', 'rowNorm', 'rowSwap', 'rowdim', 'rownorm', 'rowspace', 'rowswap', 'rref', 'rsolve', 'same', 'sample', 'samplerate', 'sans_factoriser', 'saute', 'scalarProduct', 'scalar_product', 'scatterplot', 'schur', 'sec', 'secant_solver', 'segment', 'seidel_spectrum', 'seidel_switch', 'select', 'semi_augment', 'seq', 'seqplot', 'seqsolve', 'sequence_graph', 'series', 'set_edge_attribute', 'set_edge_weight', 'set_graph_attribute', 'set_pixel', 'set_vertex_attribute', 'set_vertex_positions', 'shift', 'shift_phase', 'shortest_path', 'show_pixels', 'shuffle', 'sierpinski_graph', 'sign', 'signature', 'signe', 'similarity', 'simp2', 'simplex_reduce', 'simplifier', 'simplify', 'simpson', 'simult', 'sin', 'sin2costan', 'sincos', 'single_inter', 'sinh', 'sizes', 'slope', 'slopeat', 'slopeatraw', 'smith', 'smod', 'snedecor', 'snedecor_cdf', 'snedecor_icdf', 'snedecord', 'snedecord_cdf', 'snedecord_icdf', 'solid_line', 'solve', 'somme', 'sommet', 'sort', 'sorta', 'sortd', 'sorted', 'soundsec', 'spanning_tree', 'sphere', 'spline', 'split', 'spring', 'sq', 'sqrfree', 'sqrt', 'square', 'square_point', 'srand', 'sst', 'sst_in', 'st_ordering', 'star_graph', 'star_point', 'start', 'stdDev', 'stddev', 'stddevp', 'steffenson_solver', 'stereo2mono', 'str', 'strongly_connected_components', 'student', 'student_cdf', 'student_icdf', 'studentd', 'studentt', 'sturm', 'sturmab', 'sturmseq', 'style', 'subMat', 'subdivide_edges', 'subgraph', 'subs', 'subsop', 'subst', 'substituer', 'subtype', 'sum', 'sum_riemann', 'suppress', 'surd', 'svd', 'swapcol', 'swaprow', 'switch_axes', 'sylvester', 'symb2poly', 'symbol', 'syst2mat', 'tCollect', 'tExpand', 'table', 'tablefunc', 'tableseq', 'tabvar', 'tail', 'tan', 'tan2cossin2', 'tan2sincos', 'tan2sincos2', 'tangent', 'tangente', 'tanh', 'taux_accroissement', 'taylor', 'tchebyshev1', 'tchebyshev2', 'tcoeff', 'tcollect', 'tdeg', 'tensor_product', 'tetrahedron', 'texpand', 'thickness', 'threshold', 'throw', 'title', 'titre', 'tlin', 'tonnetz', 'topologic_sort', 'topological_sort', 'torus_grid_graph', 'total_degree', 'tourne_droite', 'tourne_gauche', 'tpsolve', 'trace', 'trail', 'trail2edges', 'trames', 'tran', 'transitive_closure', 'translation', 'transpose', 'trapeze', 'trapezoid', 'traveling_salesman', 'tree', 'tree_height', 'triangle', 'triangle_paper', 'triangle_plein', 'triangle_point', 'triangle_window', 'trig2exp', 'trigcos', 'trigexpand', 'triginterp', 'trigsimplify', 'trigsin', 'trigtan', 'trn', 'true', 'trunc', 'truncate', 'truncate_graph', 'tsimplify', 'tuer', 'tukey_window', 'tutte_polynomial', 'two_edge_connected_components', 'ufactor', 'ugamma', 'unapply', 'unarchive', 'underlying_graph', 'unfactored', 'uniform', 'uniform_cdf', 'uniform_icdf', 'uniformd', 'uniformd_cdf', 'uniformd_icdf', 'unitV', 'unquote', 'upper', 'user_operator', 'usimplify', 'valuation', 'vandermonde', 'variables_are_files', 'variance', 'version', 'vertex_connectivity', 'vertex_degree', 'vertex_distance', 'vertex_in_degree', 'vertex_out_degree', 'vertices', 'vertices_abc', 'vertices_abca', 'vpotential', 'web_graph', 'weibull', 'weibull_cdf', 'weibull_icdf', 'weibulld', 'weibulld_cdf', 'weibulld_icdf', 'weibullvariate', 'weight_matrix', 'weighted', 'weights', 'welch_window', 'wheel_graph', 'widget_size', 'wilcoxonp', 'wilcoxons', 'wilcoxont', 'with_sqrt', 'writergb', 'writewav', 'xcas_mode', 'xyztrange', 'zeros', 'ztrans'] # -missing=set(mostkeywordorig).difference(mostkeywords) +missing = set(mostkeywordorig).difference(mostkeywords) print("Missing",missing) -newkeywords=(set(mostkeywords).difference(mostkeywordorig)).difference(toremove+blacklist) +newkeywords = (set(mostkeywords).difference(mostkeywordorig)).difference(toremove+blacklist) print("\nNew Keywords found:", newkeywords) #undocumented keywords #undocumented=['posubLMQ','poslbdLMQ','VAS_positive','VAS'] -undocumented=[] +undocumented = [] -mostkeywords=mostkeywords+undocumented +mostkeywords = mostkeywords+undocumented -mostkeywords=set(mostkeywords).difference(toremove) -mostkeywords=set(mostkeywords).difference(blacklist) -mostkeywords=set(mostkeywords).difference(moremethods) -mostkeywords=list(mostkeywords) +mostkeywords = set(mostkeywords).difference(toremove) +mostkeywords = set(mostkeywords).difference(blacklist) +mostkeywords = set(mostkeywords).difference(moremethods) +mostkeywords = list(mostkeywords) mostkeywords.sort() # building auto-methods.pxi -Mi=open("auto-methods.pxi","w") +Mi = open("auto-methods.pxi","w") Mi.write("# file auto generated by mkkeywords.py\n") -s='cdef class GiacMethods_base:\n """\n Wrapper for a giac ``gen`` containing auto-generated methods.\n' -s+='\n This class does not manage the ``gen`` inside in any way. It is just\n a dumb wrapper.' -s+='\n You almost certainly want to use one of the derived class\n :class:`Pygen` instead.\n """\n\n' +s = 'cdef class GiacMethods_base:\n """\n Wrapper for a giac ``gen`` containing auto-generated methods.\n' +s += '\n This class does not manage the ``gen`` inside in any way. It is just\n a dumb wrapper.' +s += '\n You almost certainly want to use one of the derived class\n :class:`Pygen` instead.\n """\n\n' Mi.write(s) for i in mostkeywords + moremethods: diff --git a/src/sage_setup/autogen/interpreters/specs/python.py b/src/sage_setup/autogen/interpreters/specs/python.py index 86d0d95f827..c185557165f 100644 --- a/src/sage_setup/autogen/interpreters/specs/python.py +++ b/src/sage_setup/autogen/interpreters/specs/python.py @@ -289,7 +289,7 @@ def __init__(self): for (name, op) in [('neg', 'PyNumber_Negative'), ('invert', 'PyNumber_Invert'), ('abs', 'PyNumber_Absolute')]: - instrs.append(instr_unary(name, pg('S', 'S'), '%s(i0)'%op)) + instrs.append(instr_unary(name, pg('S', 'S'), '%s(i0)' % op)) self.instr_descs = instrs self._set_opcodes() # Always use ipow diff --git a/src/sage_setup/command/sage_build_ext.py b/src/sage_setup/command/sage_build_ext.py index 1a66d520903..a9c5a87a673 100644 --- a/src/sage_setup/command/sage_build_ext.py +++ b/src/sage_setup/command/sage_build_ext.py @@ -128,7 +128,7 @@ def prepare_extension(self, ext): try: os.makedirs(path) except OSError as e: - assert e.errno==errno.EEXIST, 'Cannot create %s.' % path + assert e.errno == errno.EEXIST, 'Cannot create %s.' % path depends = sources + ext.depends if not (self.force or newer_group(depends, ext_filename, 'newer')): log.debug("skipping '%s' extension (up-to-date)", ext.name) diff --git a/src/sage_setup/run_parallel.py b/src/sage_setup/run_parallel.py index c439b9da1e7..5e25cd1b6a6 100644 --- a/src/sage_setup/run_parallel.py +++ b/src/sage_setup/run_parallel.py @@ -87,7 +87,7 @@ def process_command_results(result_values): error = None for r in result_values: if r: - print("Error running command, failed with status %s."%r) + print("Error running command, failed with status %s." % r) if not keep_going: sys.exit(1) error = r @@ -126,9 +126,9 @@ def execute_list_of_commands(command_list): def plural(n,noun): if n == 1: - return "1 %s"%noun - return "%i %ss"%(n,noun) + return "1 %s" % noun + return "%i %ss" % (n,noun) - print("Executing %s (using %s)"%(plural(len(command_list),"command"), plural(nthreads,"thread"))) + print("Executing %s (using %s)" % (plural(len(command_list),"command"), plural(nthreads,"thread"))) execute_list_of_commands_in_parallel(command_list, nthreads) - print("Time to execute %s: %.2f seconds."%(plural(len(command_list),"command"), time.time() - t)) + print("Time to execute %s: %.2f seconds." % (plural(len(command_list),"command"), time.time() - t)) From 96bcf64c3c8838ed24e10318c0f4680c00238ae3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Sun, 8 Oct 2023 18:22:09 +0200 Subject: [PATCH 056/216] adding some links for Errors in the doc --- src/sage/combinat/binary_recurrence_sequences.py | 2 +- src/sage/combinat/cartesian_product.py | 2 +- src/sage/combinat/dyck_word.py | 4 ++-- src/sage/combinat/free_module.py | 3 ++- src/sage/combinat/fully_commutative_elements.py | 2 +- src/sage/combinat/integer_lists/invlex.pyx | 2 +- src/sage/combinat/nu_dyck_word.py | 4 ++-- src/sage/combinat/perfect_matching.py | 2 +- src/sage/combinat/ranker.py | 2 +- src/sage/combinat/root_system/associahedron.py | 2 +- src/sage/combinat/sf/sfa.py | 2 +- src/sage/combinat/skew_partition.py | 5 +++-- src/sage/combinat/tableau_residues.py | 2 +- src/sage/crypto/sbox.pyx | 6 +++--- src/sage/databases/sloane.py | 2 +- src/sage/ext/fast_callable.pyx | 4 ++-- src/sage/ext/memory.pyx | 2 +- src/sage/game_theory/normal_form_game.py | 4 ++-- src/sage/interfaces/expect.py | 4 ++-- src/sage/interfaces/gap.py | 2 +- src/sage/knots/knotinfo.py | 2 +- src/sage/knots/link.py | 3 ++- src/sage/quivers/homspace.py | 2 +- src/sage/quivers/morphism.py | 2 +- src/sage/quivers/path_semigroup.py | 6 +++--- src/sage/quivers/representation.py | 4 ++-- src/sage/stats/distributions/discrete_gaussian_lattice.py | 2 +- src/sage/stats/time_series.pyx | 5 +++-- src/sage/topology/cubical_complex.py | 2 +- src/sage/topology/simplicial_complex.py | 5 +++-- src/sage_docbuild/utils.py | 7 ++++--- 31 files changed, 52 insertions(+), 46 deletions(-) diff --git a/src/sage/combinat/binary_recurrence_sequences.py b/src/sage/combinat/binary_recurrence_sequences.py index ab946066d95..354d642cd8a 100644 --- a/src/sage/combinat/binary_recurrence_sequences.py +++ b/src/sage/combinat/binary_recurrence_sequences.py @@ -539,7 +539,7 @@ def pthpowers(self, p, Bound): [1] If the sequence is degenerate, and there are no ``p`` th powers, returns `[]`. Otherwise, if - there are many ``p`` th powers, raises ``ValueError``. + there are many ``p`` th powers, raises :class:`ValueError`. :: diff --git a/src/sage/combinat/cartesian_product.py b/src/sage/combinat/cartesian_product.py index 7ab49439557..cbe219ef169 100644 --- a/src/sage/combinat/cartesian_product.py +++ b/src/sage/combinat/cartesian_product.py @@ -190,7 +190,7 @@ def __len__(self): An ``int``, the number of elements in the Cartesian product. If the number of elements is infinite or does not fit into a python ``int``, a - ``TypeError`` is raised. + :class:`TypeError` is raised. .. SEEALSO:: diff --git a/src/sage/combinat/dyck_word.py b/src/sage/combinat/dyck_word.py index 80911865d49..36573003830 100644 --- a/src/sage/combinat/dyck_word.py +++ b/src/sage/combinat/dyck_word.py @@ -124,7 +124,7 @@ def replace_parens(x): - If ``x`` is a closing parenthesis, replace ``x`` with the constant ``close_symbol``. - - Raise a ``ValueError`` if ``x`` is neither an opening nor a + - Raise a :class:`ValueError` if ``x`` is neither an opening nor a closing parenthesis. .. SEEALSO:: :func:`replace_symbols` @@ -168,7 +168,7 @@ def replace_symbols(x): - If ``x`` is ``close_symbol``, replace ``x`` with ``')'``. - If ``x`` is neither ``open_symbol`` nor ``close_symbol``, a - ``ValueError`` is raised. + :class:`ValueError` is raised. .. SEEALSO:: :func:`replace_parens` diff --git a/src/sage/combinat/free_module.py b/src/sage/combinat/free_module.py index 2ad7845f0a5..2dce68651a2 100644 --- a/src/sage/combinat/free_module.py +++ b/src/sage/combinat/free_module.py @@ -699,7 +699,8 @@ def _element_constructor_(self, x): The following originally used to yield ``p[[2]] # p[[2]]``, and if there was no natural coercion between ``s`` and ``p``, this would - raise a ``NotImplementedError``. Since :trac:`15305`, this takes the + raise a :class:`NotImplementedError`. + Since :trac:`15305`, this takes the coercion between ``s`` and ``p`` and lifts it to the tensor product. :: sage: pp(a) # optional - sage.combinat diff --git a/src/sage/combinat/fully_commutative_elements.py b/src/sage/combinat/fully_commutative_elements.py index 200b98b2f36..285bd370fb1 100644 --- a/src/sage/combinat/fully_commutative_elements.py +++ b/src/sage/combinat/fully_commutative_elements.py @@ -800,7 +800,7 @@ class FullyCommutativeElements(UniqueRepresentation, Parent): True Attempting to create an element from an input that is not the reduced word - of a fully commutative element throws a ``ValueError``:: + of a fully commutative element throws a :class:`ValueError`:: sage: FC([1,2,1]) Traceback (most recent call last): diff --git a/src/sage/combinat/integer_lists/invlex.pyx b/src/sage/combinat/integer_lists/invlex.pyx index c94a024c040..f78c5d3b467 100644 --- a/src/sage/combinat/integer_lists/invlex.pyx +++ b/src/sage/combinat/integer_lists/invlex.pyx @@ -862,7 +862,7 @@ If you know what you are doing, you can set check=False to skip this warning.""" ``None`` if this method finds a proof that there exists an upper bound on the length. Otherwise a - ``ValueError`` is raised. + :class:`ValueError` is raised. EXAMPLES:: diff --git a/src/sage/combinat/nu_dyck_word.py b/src/sage/combinat/nu_dyck_word.py index 654b9a4c2a3..213fb05efc0 100644 --- a/src/sage/combinat/nu_dyck_word.py +++ b/src/sage/combinat/nu_dyck_word.py @@ -94,7 +94,7 @@ def replace_dyck_char(x): - If ``x`` is a closing character, replace ``x`` with the constant ``ndw_close_symbol``. - - Raise a ``ValueError`` if ``x`` is neither an opening nor a + - Raise a :class:`ValueError` if ``x`` is neither an opening nor a closing character. .. SEEALSO:: :func:`replace_dyck_symbol` @@ -142,7 +142,7 @@ def replace_dyck_symbol(x, open_char='N', close_char='E') -> str: - If ``x`` is ``ndw_close_symbol``, replace ``x`` with ``close_char``. - If ``x`` is neither ``ndw_open_symbol`` nor ``ndw_close_symbol``, a - ``ValueError`` is raised. + :class:`ValueError` is raised. .. SEEALSO:: :func:`replace_dyck_char` diff --git a/src/sage/combinat/perfect_matching.py b/src/sage/combinat/perfect_matching.py index c663a689f31..c9cc93fd7b3 100644 --- a/src/sage/combinat/perfect_matching.py +++ b/src/sage/combinat/perfect_matching.py @@ -130,7 +130,7 @@ def __classcall_private__(cls, parts): The function checks that the given list or permutation is a valid perfect matching (i.e. a list of pairs with pairwise disjoint elements or a fix point free involution) and raises - a ``ValueError`` otherwise:: + a :class:`ValueError` otherwise:: sage: PerfectMatching([(1, 2, 3), (4, 5)]) Traceback (most recent call last): diff --git a/src/sage/combinat/ranker.py b/src/sage/combinat/ranker.py index 6d7fb2998a2..68ae91baba3 100644 --- a/src/sage/combinat/ranker.py +++ b/src/sage/combinat/ranker.py @@ -72,7 +72,7 @@ def rank_from_list(l): sage: r('c') 2 - For non elements a ``ValueError`` is raised, as with the usual + For non elements a :class:`ValueError` is raised, as with the usual ``index`` method of lists:: sage: r('blah') diff --git a/src/sage/combinat/root_system/associahedron.py b/src/sage/combinat/root_system/associahedron.py index b0739695810..24140007081 100644 --- a/src/sage/combinat/root_system/associahedron.py +++ b/src/sage/combinat/root_system/associahedron.py @@ -337,7 +337,7 @@ class Associahedra_base(): Importantly, the parent knows the dimension of the ambient space. If you try to construct an associahedron of a different - dimension, a ``ValueError`` is raised:: + dimension, a :class:`ValueError` is raised:: sage: parent(['A',3]) Traceback (most recent call last): diff --git a/src/sage/combinat/sf/sfa.py b/src/sage/combinat/sf/sfa.py index 75649323746..3e9ac55bd70 100644 --- a/src/sage/combinat/sf/sfa.py +++ b/src/sage/combinat/sf/sfa.py @@ -6084,7 +6084,7 @@ def principal_specialization(self, n=infinity, q=None): 1 Check that the stable principal specialization at `q = 1` - raises a ``ValueError``: + raises a :class:`ValueError`: sage: def test_error(x): ....: message = "the stable principal specialization of %s at q=1 should raise a ValueError" diff --git a/src/sage/combinat/skew_partition.py b/src/sage/combinat/skew_partition.py index 92979d13a82..2aeb17b737a 100644 --- a/src/sage/combinat/skew_partition.py +++ b/src/sage/combinat/skew_partition.py @@ -1574,7 +1574,7 @@ def from_row_and_column_length(self, rowL, colL): - If it exists the unique skew-partitions with row lengths ``rowL`` and column lengths ``colL``. - - Raise a ``ValueError`` if ``rowL`` and ``colL`` are not compatible. + - Raise a :class:`ValueError` if ``rowL`` and ``colL`` are not compatible. EXAMPLES:: @@ -1604,7 +1604,8 @@ def from_row_and_column_length(self, rowL, colL): .. WARNING:: If some rows and columns have length zero, there is no way to retrieve - unambiguously the skew partition. We therefore raise a ``ValueError``. + unambiguously the skew partition. We therefore raise + a :class:`ValueError`. For examples here are two skew partitions with the same row and column lengths:: diff --git a/src/sage/combinat/tableau_residues.py b/src/sage/combinat/tableau_residues.py index 9f2748fa70c..ae3f65e7196 100644 --- a/src/sage/combinat/tableau_residues.py +++ b/src/sage/combinat/tableau_residues.py @@ -269,7 +269,7 @@ def __init__(self, parent, residues, check): def check(self): r""" - Raise a ``ValueError`` if ``self`` is not a residue sequence. + Raise a :class:`ValueError` if ``self`` is not a residue sequence. EXAMPLES:: diff --git a/src/sage/crypto/sbox.pyx b/src/sage/crypto/sbox.pyx index b72f13e30a8..e66cb52186c 100644 --- a/src/sage/crypto/sbox.pyx +++ b/src/sage/crypto/sbox.pyx @@ -417,7 +417,7 @@ cdef class SBox(SageObject): sage: all([x == id(x) for x in k]) True - Some examples for inputs that throw an ``TypeError``:: + Some examples for inputs that throw an :class:`TypeError`:: sage: S([1]*10^6) Traceback (most recent call last): @@ -1063,7 +1063,7 @@ cdef class SBox(SageObject): field is of degree ``m``. If the output length does not match the input length then a - ``TypeError`` is raised. + :class:`TypeError` is raised. INPUT: @@ -1797,7 +1797,7 @@ cdef class SBox(SageObject): Return the inverse of this S-Box. Note that the S-Box must be invertible, otherwise it will raise - a ``TypeError``. + a :class:`TypeError`. EXAMPLES:: diff --git a/src/sage/databases/sloane.py b/src/sage/databases/sloane.py index e80eb9b2518..d5802620066 100644 --- a/src/sage/databases/sloane.py +++ b/src/sage/databases/sloane.py @@ -308,7 +308,7 @@ def sequence_name(self, N): Return the name of sequence ``N`` in the encyclopedia. If sequence ``N`` does not exist, return ``''``. If the names - database is not installed, raise an ``IOError``. + database is not installed, raise an :class:`IOError`. INPUT: diff --git a/src/sage/ext/fast_callable.pyx b/src/sage/ext/fast_callable.pyx index 236822c7a32..baf2e7c6d6e 100644 --- a/src/sage/ext/fast_callable.pyx +++ b/src/sage/ext/fast_callable.pyx @@ -2659,7 +2659,7 @@ class FastCallableFloatWrapper: An instance of ``FastCallableFloatWrapper`` that can be called just like ``ff``, but that always returns a ``float`` - if no error is raised. A ``ValueError`` is raised if the + if no error is raised. A :class:`ValueError` is raised if the imaginary part of the result exceeds ``imag_tol``. EXAMPLES: @@ -2693,7 +2693,7 @@ class FastCallableFloatWrapper: TESTS: Evaluation either returns a ``float``, or raises a - ``ValueError``:: + :class:`ValueError`:: sage: # needs sage.symbolic sage: from sage.ext.fast_callable import FastCallableFloatWrapper diff --git a/src/sage/ext/memory.pyx b/src/sage/ext/memory.pyx index b95130b19dd..1e93581a370 100644 --- a/src/sage/ext/memory.pyx +++ b/src/sage/ext/memory.pyx @@ -44,7 +44,7 @@ cdef extern from "Python.h": cdef void alloc_error(size_t size) nogil: """ - Jump back to ``sig_on()``, raising a ``MemoryError``. + Jump back to ``sig_on()``, raising a :class:`MemoryError`. """ with gil: PyErr_Format(MemoryError, "failed to allocate %zu bytes", size) diff --git a/src/sage/game_theory/normal_form_game.py b/src/sage/game_theory/normal_form_game.py index cd6e371eeb2..811e00aec62 100644 --- a/src/sage/game_theory/normal_form_game.py +++ b/src/sage/game_theory/normal_form_game.py @@ -1577,8 +1577,8 @@ def obtain_nash(self, algorithm=False, maximization=True, solver=None): sage: cg.obtain_nash(algorithm='lp', solver='PPL') [[(0, 0, 1, 0), (0, 0, 1)]] - Running the constant-sum solver on a game which isn't a constant sum game - generates a ``ValueError``:: + Running the constant-sum solver on a game which is not a constant sum + game generates a :class:`ValueError`:: sage: cg = NormalFormGame([A, A]) sage: cg.obtain_nash(algorithm='lp', solver='glpk') diff --git a/src/sage/interfaces/expect.py b/src/sage/interfaces/expect.py index 30d3843852e..17ad63cfbac 100644 --- a/src/sage/interfaces/expect.py +++ b/src/sage/interfaces/expect.py @@ -800,7 +800,7 @@ def _eval_line_using_file(self, line, restart_if_needed=True): - ``restart_if_needed`` - (optional bool, default ``True``) -- If it is ``True``, the command evaluation is evaluated a second time after restarting the interface, if an - ``EOFError`` occurred. + :class:`EOFError` occurred. TESTS:: @@ -902,7 +902,7 @@ def _eval_line(self, line, allow_use_file=True, wait_for_prompt=True, restart_if - ``restart_if_needed`` (optional bool, default ``True``) -- If it is ``True``, the command evaluation is evaluated a second time after restarting the interface, if an - ``EOFError`` occurred. + :class:`EOFError` occurred. TESTS:: diff --git a/src/sage/interfaces/gap.py b/src/sage/interfaces/gap.py index dd4c87ce988..8c4ba93a25f 100644 --- a/src/sage/interfaces/gap.py +++ b/src/sage/interfaces/gap.py @@ -632,7 +632,7 @@ def _eval_line(self, line, allow_use_file=True, wait_for_prompt=True, restart_if - ``restart_if_needed`` (optional bool, default ``True``) -- If it is ``True``, the command evaluation is evaluated a second time after restarting the interface, if an - ``EOFError`` occurred. + :class:`EOFError` occurred. TESTS:: diff --git a/src/sage/knots/knotinfo.py b/src/sage/knots/knotinfo.py index 0e1e45d2cbe..380dc411158 100644 --- a/src/sage/knots/knotinfo.py +++ b/src/sage/knots/knotinfo.py @@ -1913,7 +1913,7 @@ def link(self, use_item=db.columns().pd_notation, snappy=False): the target of the conversion is the ``pip`` installable package `SnapPy `__ (explicitely, ``spherogram.links.invariants.Link``). - If SnapPy is not installed an ``ImportError`` is raised. To + If SnapPy is not installed an :class:`ImportError` is raised. To install SnapPy use ``sage -pip install snappy``. .. NOTE:: diff --git a/src/sage/knots/link.py b/src/sage/knots/link.py index a5ecdb5490c..d5986d3ad44 100644 --- a/src/sage/knots/link.py +++ b/src/sage/knots/link.py @@ -3837,7 +3837,8 @@ def get_knotinfo(self, mirror_version=True, unique=True): If ``mirror_version`` is set to ``False`` then the result is just ``K`` (that is: ``m`` is suppressed). - If it is not possible to determine a unique result a ``NotImplementedError`` + If it is not possible to determine a unique result + a :class:`NotImplementedError` will be raised. To avoid this you can set ``unique`` to ``False``. You will get a list of matching candidates instead. diff --git a/src/sage/quivers/homspace.py b/src/sage/quivers/homspace.py index cb9a36e3eed..414eafa5a89 100644 --- a/src/sage/quivers/homspace.py +++ b/src/sage/quivers/homspace.py @@ -45,7 +45,7 @@ class QuiverHomSpace(Homset): .. NOTE:: The quivers of the domain and codomain must be equal or a - ``ValueError`` is raised. + :class:`ValueError` is raised. EXAMPLES:: diff --git a/src/sage/quivers/morphism.py b/src/sage/quivers/morphism.py index fc08e35ba60..7fcbb501151 100644 --- a/src/sage/quivers/morphism.py +++ b/src/sage/quivers/morphism.py @@ -616,7 +616,7 @@ def __mul__(self, other): def _assert_valid_hom(self): """ - Raise a ``ValueError`` if the homomorphism is not well defined. + Raise a :class:`ValueError` if the homomorphism is not well defined. Specifically it checks that the domain and codomains of the maps are correct and that the edge diagrams commute. diff --git a/src/sage/quivers/path_semigroup.py b/src/sage/quivers/path_semigroup.py index d592595e4c9..85aea6517d0 100644 --- a/src/sage/quivers/path_semigroup.py +++ b/src/sage/quivers/path_semigroup.py @@ -295,8 +295,8 @@ def _element_constructor_(self, data, check=True): sage: Q(P(['c','d'])) c*d - A ``TypeError`` or a ``ValueError`` is raised appropriately if the input - is wrong:: + A :class:`TypeError` or a :class:`ValueError` is raised appropriately + if the input is wrong:: sage: G = DiGraph([(0,0,'a'), (0,1,'b'), (1,0,'c')], loops=True) sage: P = G.path_semigroup() @@ -1079,7 +1079,7 @@ def all_paths(self, start=None, end=None): ... ValueError: the end vertex 4 is not a vertex of the quiver - If the underlying quiver is cyclic, a ``ValueError`` + If the underlying quiver is cyclic, a :class:`ValueError` is raised:: sage: Q = DiGraph({1:{2:['a','b'], 3:['c']}, 3:{1:['d']}}) diff --git a/src/sage/quivers/representation.py b/src/sage/quivers/representation.py index db82cbd7c86..4d8b3cf7321 100644 --- a/src/sage/quivers/representation.py +++ b/src/sage/quivers/representation.py @@ -502,7 +502,7 @@ class QuiverRepFactory(UniqueFactory): - ``basis`` - list; a nonempty list of paths in the quiver ``Q``. Entries that do not represent valid paths are ignored and duplicate paths are deleted. There must be at least one valid path in the list - or a ``ValueError`` is raised. The closure of this list under right + or a :class:`ValueError` is raised. The closure of this list under right multiplication forms the basis of the resulting representation. The third option is the ``dual paths`` option which creates the dual of @@ -516,7 +516,7 @@ class QuiverRepFactory(UniqueFactory): - ``basis`` -- list; a nonempty list of paths in the quiver ``Q``. Entries that do not represent valid paths are ignored and duplicate paths are deleted. There must be at least one valid path in the list - or a ``ValueError`` is raised. The closure of this list under left + or a :class:`ValueError` is raised. The closure of this list under left multiplication of edges forms the basis of the resulting representation. Using the second and third options requires that the following keyword be diff --git a/src/sage/stats/distributions/discrete_gaussian_lattice.py b/src/sage/stats/distributions/discrete_gaussian_lattice.py index 8e35d45129f..08790bf92be 100644 --- a/src/sage/stats/distributions/discrete_gaussian_lattice.py +++ b/src/sage/stats/distributions/discrete_gaussian_lattice.py @@ -192,7 +192,7 @@ def _normalisation_factor_zz(self, tau=3): over all probabilities is 1 for `\ZZⁿ`. If this ``self.B`` is not an identity matrix over `\ZZ` a - ``NotImplementedError`` is raised. + :class:`NotImplementedError` is raised. INPUT: diff --git a/src/sage/stats/time_series.pyx b/src/sage/stats/time_series.pyx index 4a0e9f868db..1ef69068015 100644 --- a/src/sage/stats/time_series.pyx +++ b/src/sage/stats/time_series.pyx @@ -1725,8 +1725,9 @@ cdef class TimeSeries: def min(self, bint index=False): r""" - Return the smallest value in this time series. If this series - has length 0 we raise a ``ValueError``. + Return the smallest value in this time series. + + If this series has length 0, we raise a :class:`ValueError`. INPUT: diff --git a/src/sage/topology/cubical_complex.py b/src/sage/topology/cubical_complex.py index c26ff4e08bb..e31bbef30c6 100644 --- a/src/sage/topology/cubical_complex.py +++ b/src/sage/topology/cubical_complex.py @@ -106,7 +106,7 @@ class Cube(SageObject): Each cube is stored in a standard form: a tuple of tuples, with a nondegenerate interval ``[j,j]`` represented by ``(j,j)``, not ``(j,)``. (This is so that for any interval ``I``, ``I[1]`` will - produce a value, not an ``IndexError``.) + produce a value, not an :class:`IndexError`.) EXAMPLES:: diff --git a/src/sage/topology/simplicial_complex.py b/src/sage/topology/simplicial_complex.py index 1d00dd50a4d..e3b8f9a853c 100644 --- a/src/sage/topology/simplicial_complex.py +++ b/src/sage/topology/simplicial_complex.py @@ -1141,7 +1141,7 @@ def __hash__(self): Compute the hash value of ``self``. If this simplicial complex is immutable, it computes the hash value - based upon the facets. Otherwise it raises a ``ValueError``. + based upon the facets. Otherwise it raises a :class`ValueError`. EXAMPLES:: @@ -1268,7 +1268,8 @@ def __contains__(self, x): def __call__(self, simplex): """ If ``simplex`` is a simplex in this complex, return it. - Otherwise, raise a ``ValueError``. + + Otherwise, this raises a :class:`ValueError`. EXAMPLES:: diff --git a/src/sage_docbuild/utils.py b/src/sage_docbuild/utils.py index 196f761650e..28677d9b6c4 100644 --- a/src/sage_docbuild/utils.py +++ b/src/sage_docbuild/utils.py @@ -98,7 +98,8 @@ 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 :class:`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, @@ -175,8 +176,8 @@ 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 - started:: + gracefully, but then a :class:`RuntimeError` is raised and pending tasks + are not started:: sage: def target(N): ....: import time, os, signal From a0c91899d00e88ec9f01e9ce99e2223e54dcda1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Sun, 8 Oct 2023 20:13:03 +0200 Subject: [PATCH 057/216] cleanup of gap3 interface file --- src/sage/interfaces/gap3.py | 197 +++++++++++++++++++----------------- 1 file changed, 106 insertions(+), 91 deletions(-) diff --git a/src/sage/interfaces/gap3.py b/src/sage/interfaces/gap3.py index beef28e562a..95cdbad6cf1 100644 --- a/src/sage/interfaces/gap3.py +++ b/src/sage/interfaces/gap3.py @@ -55,18 +55,20 @@ #. ``gap3(expr)`` - Evaluation of arbitrary GAP3 expressions, with the result returned as a Sage object wrapping the corresponding GAP3 element:: - sage: a = gap3('3+2') #optional - gap3 - sage: a #optional - gap3 + sage: # optional - gap3 + sage: a = gap3('3+2') + sage: a 5 - sage: type(a) #optional - gap3 + sage: type(a) :: - sage: S5 = gap3('SymmetricGroup(5)') #optional - gap3 - sage: S5 #optional - gap3 + sage: # optional - gap3 + sage: S5 = gap3('SymmetricGroup(5)') + sage: S5 Group( (1,5), (2,5), (3,5), (4,5) ) - sage: type(S5) #optional - gap3 + sage: type(S5) This provides a Pythonic interface to GAP3. If ``gap_function`` is the @@ -74,9 +76,10 @@ returns the ``gap_element`` obtained by evaluating the command ``gap_function(gap_element)`` in GAP3:: - sage: S5.Size() #optional - gap3 + sage: # optional - gap3 + sage: S5.Size() 120 - sage: S5.CharTable() #optional - gap3 + sage: S5.CharTable() CharTable( Group( (1,5), (2,5), (3,5), (4,5) ) ) Alternatively, you can instead use the syntax @@ -91,18 +94,19 @@ ``gap_element.recfield`` provides a means to access the record element corresponding to the field ``recfield``:: - sage: S5.IsRec() #optional - gap3 + sage: # optional - gap3 + sage: S5.IsRec() true - sage: S5.recfields() #optional - gap3 + sage: S5.recfields() ['isDomain', 'isGroup', 'identity', 'generators', 'operations', 'isPermGroup', 'isFinite', '1', '2', '3', '4', 'degree'] - sage: S5.identity #optional - gap3 + sage: S5.identity () - sage: S5.degree #optional - gap3 + sage: S5.degree 5 - sage: S5.1 #optional - gap3 + sage: S5.1 (1,5) - sage: S5.2 #optional - gap3 + sage: S5.2 (2,5) #. By typing ``%gap3`` or ``gap3.interact()`` at the command-line, you can @@ -172,39 +176,42 @@ Load a GAP3 package:: - sage: gap3.load_package("chevie") #optional - gap3 - sage: gap3.version() # random #optional - gap3 + sage: # optional - gap3 + sage: gap3.load_package("chevie") + sage: gap3.version() # random 'lib: v3r4p4 1997/04/18, src: v3r4p0 1994/07/10, sys: usg gcc ansi' Working with GAP3 lists. Note that GAP3 lists are 1-indexed:: - sage: L = gap3([1,2,3]) #optional - gap3 - sage: L[1] #optional - gap3 + sage: # optional - gap3 + sage: L = gap3([1,2,3]) + sage: L[1] 1 - sage: L[2] #optional - gap3 + sage: L[2] 2 - sage: 3 in L #optional - gap3 + sage: 3 in L True - sage: 4 in L #optional - gap3 + sage: 4 in L False - sage: m = gap3([[1,2],[3,4]]) #optional - gap3 - sage: m[2,1] #optional - gap3 + sage: m = gap3([[1,2],[3,4]]) + sage: m[2,1] 3 - sage: [1,2] in m #optional - gap3 + sage: [1,2] in m True - sage: [3,2] in m #optional - gap3 + sage: [3,2] in m False - sage: gap3([1,2]) in m #optional - gap3 + sage: gap3([1,2]) in m True Controlling variable names used by GAP3:: - sage: gap3('2', name='x') #optional - gap3 + sage: # optional - gap3 + sage: gap3('2', name='x') 2 - sage: gap3('x') #optional - gap3 + sage: gap3('x') 2 - sage: gap3.unbind('x') #optional - gap3 - sage: gap3('x') #optional - gap3 + sage: gap3.unbind('x') + sage: gap3('x') Traceback (most recent call last): ... TypeError: Gap3 produced error output @@ -226,6 +233,7 @@ # # https://www.gnu.org/licenses/ # **************************************************************************** +import os from sage.misc.cachefunc import cached_method from sage.interfaces.expect import Expect @@ -311,21 +319,21 @@ def __init__(self, command=gap3_cmd): # lines of text are output by GAP3 before the pager is invoked. # This option is useful in dealing with the GAP3 help system. Expect.__init__(self, - name='gap3', - prompt='gap> ', - command=self.__gap3_command_string + " -p -b -y 500", - server=None, - ulimit=None, - script_subdirectory=None, - restart_on_ctrlc=True, - verbose_start=False, - init_code=[], - max_startup_time=None, - logfile=None, - eval_using_file_cutoff=100, - do_cleaner=True, - remote_cleaner=False, - path=None) + name='gap3', + prompt='gap> ', + command=self.__gap3_command_string + " -p -b -y 500", + server=None, + ulimit=None, + script_subdirectory=None, + restart_on_ctrlc=True, + verbose_start=False, + init_code=[], + max_startup_time=None, + logfile=None, + eval_using_file_cutoff=100, + do_cleaner=True, + remote_cleaner=False, + path=None) def _start(self): r""" @@ -351,8 +359,8 @@ def _start(self): # funny-looking patterns in the interface. We compile the patterns # now, and use them later for interpreting interface messages. self._compiled_full_pattern = self._expect.compile_pattern_list([ - r'@p\d+\.','@@','@[A-Z]',r'@[123456!"#$%&][^+]*\+', '@e','@c', - '@f','@h','@i','@m','@n','@r',r'@s\d',r'@w.*\+','@x','@z']) + r'@p\d+\.', '@@', '@[A-Z]', r'@[123456!"#$%&][^+]*\+', '@e', '@c', + '@f', '@h', '@i', '@m', '@n', '@r', r'@s\d', r'@w.*\+', '@x', '@z']) self._compiled_small_pattern = self._expect.compile_pattern_list('@J') self._expect.expect("@i") @@ -416,7 +424,7 @@ def _execute_line(self, line, wait_for_prompt=True, expect_eof=False): # messages, so the generic GAP interface processing code does not # detect it. So we test for a syntax error explicitly. normal_output, error_output = \ - super(Gap3, self)._execute_line(line, wait_for_prompt=True, expect_eof=False) + super()._execute_line(line, wait_for_prompt=True, expect_eof=False) normal = bytes_to_str(normal_output) if normal.startswith("Syntax error:"): normal_output, error_output = "", normal_output @@ -445,19 +453,20 @@ def help(self, topic, pager=True): TESTS:: - sage: m = gap3([[1,2,3],[4,5,6]]); m #optional - gap3 + sage: # optional - gap3 + sage: m = gap3([[1,2,3],[4,5,6]]); m [ [ 1, 2, 3 ], [ 4, 5, 6 ] ] - sage: gap3.help('help', pager=False) #optional - gap3 + sage: gap3.help('help', pager=False) Help _______________________________________________________... - sage: m #optional - gap3 + sage: m [ [ 1, 2, 3 ], [ 4, 5, 6 ] ] - sage: m.Print() #optional - gap3 + sage: m.Print() [ [ 1, 2, 3 ], [ 4, 5, 6 ] ] - sage: gap3.help('Group', pager=False) #optional - gap3 + sage: gap3.help('Group', pager=False) Group ______________________________________________________... - sage: m #optional - gap3 + sage: m [ [ 1, 2, 3 ], [ 4, 5, 6 ] ] - sage: m.Print() #optional - gap3 + sage: m.Print() [ [ 1, 2, 3 ], [ 4, 5, 6 ] ] """ @@ -485,7 +494,7 @@ def help(self, topic, pager=True): helptext.append(E.before) elif x == 2: # matched a special char; convert and insert - helptext.append(chr(ord(E.after[1:2])-ord('A')+1)) + helptext.append(chr(ord(E.after[1:2]) - ord('A') + 1)) helptext.append(E.before) elif x == 10: # matched @n (normal input mode); it seems we're done @@ -510,20 +519,21 @@ def cputime(self, t=None): EXAMPLES:: - sage: t = gap3.cputime() #optional - gap3 - sage: t #random #optional - gap3 + sage: # optional - gap3 + sage: t = gap3.cputime() + sage: t #random 0.02 - sage: gap3.SymmetricGroup(5).Size() #optional - gap3 + sage: gap3.SymmetricGroup(5).Size() 120 - sage: gap3.cputime() #random #optional - gap3 + sage: gap3.cputime() #random 0.14999999999999999 - sage: gap3.cputime(t) #random #optional - gap3 + sage: gap3.cputime(t) #random 0.13 """ if t is not None: return self.cputime() - t else: - return eval(self.eval('Runtime();'))/1000.0 + return eval(self.eval('Runtime();')) / 1000.0 def console(self): r""" @@ -658,11 +668,12 @@ class GAP3Element(GapElement_generic): EXAMPLES:: - sage: from sage.interfaces.gap3 import GAP3Element #optional - gap3 - sage: gap3 = Gap3() #optional - gap3 - sage: GAP3Element(gap3, value='3+2') #optional - gap3 + sage: # optional - gap3 + sage: from sage.interfaces.gap3 import GAP3Element + sage: gap3 = Gap3() + sage: GAP3Element(gap3, value='3+2') 5 - sage: GAP3Element(gap3, value='sage0', is_name=True) #optional - gap3 + sage: GAP3Element(gap3, value='sage0', is_name=True) 5 TESTS:: @@ -682,11 +693,12 @@ def __init__(self, parent, value, is_name=False, name=None): EXAMPLES:: - sage: from sage.interfaces.gap3 import GAP3Element #optional - gap3 - sage: gap3 = Gap3() #optional - gap3 - sage: GAP3Element(gap3, value='3+2') #optional - gap3 + sage: # optional - gap3 + sage: from sage.interfaces.gap3 import GAP3Element + sage: gap3 = Gap3() + sage: GAP3Element(gap3, value='3+2') 5 - sage: GAP3Element(gap3, value='sage0', is_name=True) #optional - gap3 + sage: GAP3Element(gap3, value='sage0', is_name=True) 5 TESTS:: @@ -698,11 +710,11 @@ def __init__(self, parent, value, is_name=False, name=None): """ # Warning: One should not redefine E, X or Z in gap3, because # things will break, but gap3 raises no errors if one does this! - if name in ["E","X","Z"]: + if name in ["E", "X", "Z"]: raise ValueError("you are attempting to redefine %s; but you should never redefine E, X or Z in gap3 (because things will break!)" % name) # initialize the superclass - super(GAP3Element, self).__init__(parent, value, is_name, name) + super().__init__(parent, value, is_name, name) # check for a GAP record; if so then change the class parent._synchronize() @@ -713,16 +725,17 @@ def __getitem__(self, n): r""" EXAMPLES:: - sage: l = gap3('[1,2,3]') #optional - gap3 - sage: l[1] #optional - gap3 + sage: # optional - gap3 + sage: l = gap3('[1,2,3]') + sage: l[1] 1 - sage: a = gap3([1,2,3]) #optional - gap3 - sage: a[1] #optional - gap3 + sage: a = gap3([1,2,3]) + sage: a[1] 1 - sage: m = gap3([[1,2,3],[4,5,6],[7,8,9]]) #optional - gap3 - sage: m[1,3] #optional - gap3 + sage: m = gap3([[1,2,3],[4,5,6],[7,8,9]]) + sage: m[1,3] 3 - sage: m[2][1] #optional - gap3 + sage: m[2][1] 4 """ gap3_session = self._check_valid() @@ -744,12 +757,13 @@ def _latex_(self): gap3_session = self._check_valid() try: s = gap3_session.eval('FormatLaTeX(%s)' % self.name()) - s = s.replace('\\\\','\\').replace('"','') - s = s.replace('%\\n',' ') + s = s.replace('\\\\', '\\').replace('"', '') + s = s.replace('%\\n', ' ') return s except RuntimeError: return str(self) + class GAP3Record(GAP3Element): r""" A GAP3 record @@ -786,9 +800,9 @@ def recfields(self): gap3_session = self._check_valid() if not hasattr(self, "_gap_recfields"): s = str(gap3_session.eval("RecFields(%s)" % self._name)) - s = s.strip('[] ').replace('\n','') + s = s.strip('[] ').replace('\n', '') self._gap_recfields = [ss.strip('" ') for ss in s.split(',')] - return getattr(self,"_gap_recfields") + return getattr(self, "_gap_recfields") def operations(self): r""" @@ -811,11 +825,11 @@ def operations(self): [ (1,2,5), (1,3,5), (1,4,5) ] ) ] """ gap3_session = self._check_valid() - if not hasattr(self,"_gap_operations"): + if not hasattr(self, "_gap_operations"): s = str(gap3_session.eval("RecFields(%s.operations)" % self._name)) - s = s.strip('[] ').replace('\n','') + s = s.strip('[] ').replace('\n', '') self._gap_operations = [ss.strip('" ') for ss in s.split(',')] - return getattr(self,"_gap_operations") + return getattr(self, "_gap_operations") def __getattr__(self, attrname): r""" @@ -827,12 +841,13 @@ def __getattr__(self, attrname): EXAMPLES:: - sage: S5 = gap3.SymmetricGroup(5) #optional - gap3 - sage: S5.__getattr__('Size') #optional - gap3 + sage: # optional - gap3 + sage: S5 = gap3.SymmetricGroup(5) + sage: S5.__getattr__('Size') Size - sage: gap3.IsFunc(S5.__getattr__('Size')) #optional - gap3 + sage: gap3.IsFunc(S5.__getattr__('Size')) true - sage: S5.__getattr__('generators') #optional - gap3 + sage: S5.__getattr__('generators') [ (1,5), (2,5), (3,5), (4,5) ] """ gap3_session = self._check_valid() @@ -865,7 +880,6 @@ def _tab_completion(self): return names -import os def gap3_console(): r""" Spawn a new GAP3 command-line session. @@ -903,6 +917,7 @@ def gap3_console(): raise RuntimeError('Can use the console only in the terminal. Try %%gap3 magics instead.') os.system(gap3_cmd) + def gap3_version(): r""" Return the version of GAP3 that you have in your PATH on your computer. From 60d973f01760558b77416fee4df0d9b146663c43 Mon Sep 17 00:00:00 2001 From: Dima Pasechnik Date: Tue, 3 Oct 2023 14:06:17 +0100 Subject: [PATCH 058/216] checking that the system maxima has working help This is needed for e.g. building Sage docs, cf e.g. Sage's #36028. Some distos mix this up. This fix was requested there. --- build/pkgs/maxima/spkg-configure.m4 | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/build/pkgs/maxima/spkg-configure.m4 b/build/pkgs/maxima/spkg-configure.m4 index 86de8c1dfc1..7a9c276fdbc 100644 --- a/build/pkgs/maxima/spkg-configure.m4 +++ b/build/pkgs/maxima/spkg-configure.m4 @@ -24,6 +24,13 @@ SAGE_SPKG_CONFIGURE([maxima], [ AS_IF([ecl --eval "(require 'maxima)" --eval "(quit)" \ >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD], [ AC_MSG_RESULT(yes) + dnl check also for the Maxima help - needed by Sage + AC_MSG_CHECKING([if maxima help is working]) + maxima_help_ok=`echo ? ? | ${SAGE_MAXIMA} 2>&1 | grep Couldn` + AS_IF([test x$maxima_help_ok = x], [AC_MSG_RESULT(yes)], [ + AC_MSG_RESULT(no) + sage_spkg_install_maxima=yes + ]) ], [ AC_MSG_RESULT(no) sage_spkg_install_maxima=yes From 913de89c6f9fd066fb88414d16e2db87e9752769 Mon Sep 17 00:00:00 2001 From: Dima Pasechnik Date: Tue, 3 Oct 2023 15:14:20 +0100 Subject: [PATCH 059/216] a better pattern --- build/pkgs/maxima/spkg-configure.m4 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/pkgs/maxima/spkg-configure.m4 b/build/pkgs/maxima/spkg-configure.m4 index 7a9c276fdbc..aac8e3f210c 100644 --- a/build/pkgs/maxima/spkg-configure.m4 +++ b/build/pkgs/maxima/spkg-configure.m4 @@ -26,7 +26,7 @@ SAGE_SPKG_CONFIGURE([maxima], [ AC_MSG_RESULT(yes) dnl check also for the Maxima help - needed by Sage AC_MSG_CHECKING([if maxima help is working]) - maxima_help_ok=`echo ? ? | ${SAGE_MAXIMA} 2>&1 | grep Couldn` + maxima_help_ok=`echo ? ? | ${SAGE_MAXIMA} 2>&1 | grep Details\:` AS_IF([test x$maxima_help_ok = x], [AC_MSG_RESULT(yes)], [ AC_MSG_RESULT(no) sage_spkg_install_maxima=yes From ef67ba0167b19a5a200936a35b289820ba4bdb57 Mon Sep 17 00:00:00 2001 From: Dima Pasechnik Date: Sun, 8 Oct 2023 12:40:41 +0100 Subject: [PATCH 060/216] trying to clean up /etc/pacman --- build/bin/write-dockerfile.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/build/bin/write-dockerfile.sh b/build/bin/write-dockerfile.sh index 530c2c6ec63..ed5d773793c 100755 --- a/build/bin/write-dockerfile.sh +++ b/build/bin/write-dockerfile.sh @@ -104,6 +104,9 @@ EOF UPDATE="pacman -Sy &&" EXISTS="pacman -Si" INSTALL="pacman -Su --noconfirm" + cat < Date: Sun, 8 Oct 2023 13:04:06 -0700 Subject: [PATCH 061/216] sage --package list: Sort output, add switches --{in,ex}clude-dependencies, handle --exclude at the end --- bootstrap | 8 ++-- build/bin/sage-package | 2 +- build/sage_bootstrap/app.py | 4 +- build/sage_bootstrap/cmdline.py | 28 ++++++++++--- build/sage_bootstrap/expand_class.py | 61 +++++++++++++++++++++++----- build/sage_bootstrap/package.py | 40 ++++++++++++++++++ src/doc/bootstrap | 10 ++--- 7 files changed, 125 insertions(+), 28 deletions(-) diff --git a/bootstrap b/bootstrap index 54d0a156239..82e42789250 100755 --- a/bootstrap +++ b/bootstrap @@ -47,12 +47,12 @@ bootstrap () { done 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:); 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:); do # Issue #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 @@ -71,7 +71,7 @@ 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); do echo "m4_sinclude([build/pkgs/$pkgname/spkg-configure.m4])" config="SAGE_SPKG_CONFIGURE_$(echo ${pkgname} | tr '[a-z]' '[A-Z]')" if grep -q SAGE_PYTHON_PACKAGE_CHECK build/pkgs/$pkgname/spkg-configure.m4; then @@ -86,7 +86,7 @@ $config" $spkg_configures $spkg_configures_python EOF - for pkgname in $(sage-package list | sort); do + for pkgname in $(sage-package list); do DIR=build/pkgs/$pkgname pkgtype="$(cat $DIR/type)" if test -f "$DIR/requirements.txt"; then diff --git a/build/bin/sage-package b/build/bin/sage-package index ccb3ad194a7..02a07140875 100755 --- a/build/bin/sage-package +++ b/build/bin/sage-package @@ -13,7 +13,7 @@ # # * Print a list of all available packages # -# $ sage-package list | sort +# $ sage-package list # 4ti2 # arb # autotools diff --git a/build/sage_bootstrap/app.py b/build/sage_bootstrap/app.py index 22fb252410b..8c17541a9b7 100644 --- a/build/sage_bootstrap/app.py +++ b/build/sage_bootstrap/app.py @@ -53,7 +53,7 @@ def list_cls(self, *package_classes, **filters): """ Print a list of all available packages - $ sage --package list | sort + $ sage --package list 4ti2 arb autotools @@ -63,7 +63,7 @@ def list_cls(self, *package_classes, **filters): $ sage -package list --has-file=spkg-configure.m4 :experimental: perl_term_readline_gnu - $ sage -package list --has-file=spkg-configure.m4 --has-file=distros/debian.txt | sort + $ sage -package list --has-file=spkg-configure.m4 --has-file=distros/debian.txt arb boost_cropped brial diff --git a/build/sage_bootstrap/cmdline.py b/build/sage_bootstrap/cmdline.py index ca89b4fedac..c62ca6d3a01 100644 --- a/build/sage_bootstrap/cmdline.py +++ b/build/sage_bootstrap/cmdline.py @@ -64,18 +64,18 @@ epilog_list = \ """ -Print a list of packages known to Sage +Print a list of packages known to Sage (sorted alphabetically) EXAMPLE: - $ sage --package list | sort + $ sage --package list 4ti2 arb autotools [...] zlib - $ sage --package list :standard: | sort + $ sage --package list :standard: arb backports_ssl_match_hostname [...] @@ -214,7 +214,7 @@ def make_parser(): help='Print a list of packages known to Sage') parser_list.add_argument( 'package_class', metavar='[package_name|:package_type:]', - type=str, default=[':all:'], nargs='*', + type=str, default=[':all-or-nothing:'], nargs='*', help=('package name or designator for all packages of a given type ' '(one of :all:, :standard:, :optional:, and :experimental:); ' 'default: :all:')) @@ -227,8 +227,15 @@ def make_parser(): help=('only include packages that do not have this file in their metadata directory ' '(examples: huge, patches, huge|has_nonfree_dependencies)')) parser_list.add_argument( - '--exclude', action='append', default=[], metavar='PACKAGE_NAME', + '--exclude', nargs='*', action='append', default=[], metavar='PACKAGE_NAME', help='exclude package from list') + parser_list.add_argument( + '--include-dependencies', action='store_true', + help='include (ordinary) dependencies of the packages recursively') + parser_list.add_argument( + '--exclude-dependencies', action='store_true', + help='exclude (ordinary) dependencies of the packages recursively') + parser_name = subparsers.add_parser( 'name', epilog=epilog_name, formatter_class=argparse.RawDescriptionHelpFormatter, @@ -353,7 +360,16 @@ def run(): if args.subcommand == 'config': app.config() elif args.subcommand == 'list': - app.list_cls(*args.package_class, has_files=args.has_files, no_files=args.no_files, exclude=args.exclude) + if args.package_class == [':all-or-nothing:']: + if args.include_dependencies or args.exclude_dependencies: + args.package_class = [] + else: + args.package_class = [':all:'] + app.list_cls(*args.package_class, + has_files=args.has_files, no_files=args.no_files, + exclude=args.exclude, + include_dependencies=args.include_dependencies, + exclude_dependencies=args.exclude_dependencies) elif args.subcommand == 'name': app.name(args.tarball_filename) elif args.subcommand == 'tarball': diff --git a/build/sage_bootstrap/expand_class.py b/build/sage_bootstrap/expand_class.py index 10ec907d0fa..fb2c88f6e97 100644 --- a/build/sage_bootstrap/expand_class.py +++ b/build/sage_bootstrap/expand_class.py @@ -21,17 +21,19 @@ class PackageClass(object): - def __init__(self, *package_names_or_classes, **filters): - self.names = [] + def __init__(self, *package_names_or_classes, exclude=(), + include_dependencies=False, exclude_dependencies=False, + **filters): + self.__names = set() filenames = filters.pop('has_files', []) no_filenames = filters.pop('no_files', []) - excluded = filters.pop('exclude', []) + excluded = [] + for package_names in exclude: + excluded.extend(package_names) if filters: raise ValueError('filter not supported') def included_in_filter(pkg): - if pkg.name in excluded: - return False if not all(any(pkg.has_file(filename) for filename in filename_disjunction.split('|')) for filename_disjunction in filenames): @@ -55,19 +57,58 @@ def included_in_filter(pkg): 'which must be one of ' ':all:, :standard:, :optional:, or :experimental:' 'got {}'.format(package_name_or_class)) - self.names.append(package_name_or_class) + self.__names.add(package_name_or_class) + + def include_recursive_dependencies(names, package_name): + if package_name in names: + return + try: + pkg = Package(package_name) + except FileNotFoundError: + # Silently ignore unknown packages, + # substitutions such as $(BLAS) $(PYTHON), + # and optional dependencies of the form $(find-string ...). + return + names.add(package_name) + for dependency in pkg.dependencies: + include_recursive_dependencies(names, dependency) + + if include_dependencies: + package_names = set() + for name in self.__names: + include_recursive_dependencies(package_names, name) + self.__names = package_names + + def exclude_recursive_dependencies(names, package_name): + try: + pkg = Package(package_name) + except FileNotFoundError: + return + for dependency in pkg.dependencies: + names.discard(dependency) + exclude_recursive_dependencies(names, dependency) + + if exclude_dependencies: + for name in list(self.__names): + exclude_recursive_dependencies(self.__names, name) + + self.__names.difference_update(excluded) + + @property + def names(self): + return sorted(self.__names) def _init_all(self, predicate): - self.names.extend(pkg.name for pkg in Package.all() if predicate(pkg)) + self.__names.update(pkg.name for pkg in Package.all() if predicate(pkg)) def _init_standard(self, predicate): - self.names.extend(pkg.name for pkg in Package.all() if pkg.type == 'standard' and predicate(pkg)) + self.__names.update(pkg.name for pkg in Package.all() if pkg.type == 'standard' and predicate(pkg)) def _init_optional(self, predicate): - self.names.extend(pkg.name for pkg in Package.all() if pkg.type == 'optional' and predicate(pkg)) + self.__names.update(pkg.name for pkg in Package.all() if pkg.type == 'optional' and predicate(pkg)) def _init_experimental(self, predicate): - self.names.extend(pkg.name for pkg in Package.all() if pkg.type == 'experimental' and predicate(pkg)) + self.__names.update(pkg.name for pkg in Package.all() if pkg.type == 'experimental' and predicate(pkg)) def apply(self, function, *args, **kwds): for package_name in self.names: diff --git a/build/sage_bootstrap/package.py b/build/sage_bootstrap/package.py index 15b342223c4..8f8f1477261 100644 --- a/build/sage_bootstrap/package.py +++ b/build/sage_bootstrap/package.py @@ -47,6 +47,7 @@ def __init__(self, package_name): self._init_version() self._init_type() self._init_install_requires() + self._init_dependencies() def __repr__(self): return 'Package {0}'.format(self.name) @@ -245,6 +246,28 @@ def distribution_name(self): return part return None + @property + def dependencies(self): + """ + Return a list of strings, the package names of the (ordinary) dependencies + """ + # after a '|', we have order-only dependencies + return self.__dependencies.partition('|')[0].strip().split() + + @property + def dependencies_order_only(self): + """ + Return a list of strings, the package names of the order-only dependencies + """ + return self.__dependencies.partition('|')[2].strip().split() + self.__dependencies_order_only.strip().split() + + @property + def dependencies_check(self): + """ + Return a list of strings, the package names of the check dependencies + """ + return self.__dependencies_order_only.strip().split() + def __eq__(self, other): return self.tarball == other.tarball @@ -335,3 +358,20 @@ def _init_install_requires(self): self.__install_requires = f.read().strip() except IOError: self.__install_requires = None + + def _init_dependencies(self): + try: + with open(os.path.join(self.path, 'dependencies')) as f: + self.__dependencies = f.readline().strip() + except IOError: + self.__dependencies = '' + try: + with open(os.path.join(self.path, 'dependencies_check')) as f: + self.__dependencies_check = f.readline().strip() + except IOError: + self.__dependencies_check = '' + try: + with open(os.path.join(self.path, 'dependencies_order_only')) as f: + self.__dependencies_order_only = f.readline() + except IOError: + self.__dependencies_order_only = '' diff --git a/src/doc/bootstrap b/src/doc/bootstrap index be2168af064..fde83e4fd1b 100755 --- a/src/doc/bootstrap +++ b/src/doc/bootstrap @@ -100,7 +100,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: | grep -v '^sagemath_' | sort); do +for PKG_BASE in $(sage-package list --has-file SPKG.rst :standard: | grep -v '^sagemath_'); do echo "* :ref:\`spkg_$PKG_BASE\`" done >> "$OUTPUT_INDEX" cat >> "$OUTPUT_INDEX" <> "$OUTPUT_INDEX" cat >> "$OUTPUT_INDEX" <> "$OUTPUT_INDEX" cat >> "$OUTPUT_INDEX" <> "$OUTPUT_INDEX" @@ -203,7 +203,7 @@ Packages are in alphabetical order. :maxdepth: 1 EOF -for PKG_BASE in $(sage-package list --has-file SPKG.rst | sort); do +for PKG_BASE in $(sage-package list --has-file SPKG.rst); do PKG_SCRIPTS=build/pkgs/$PKG_BASE # Instead of just copying, we may want to call # a version of sage-spkg-info to format extra information. From bc7d33eeffd72b269b1f4ae7acbc0bbe3670d40e Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 6 Oct 2023 15:23:30 -0700 Subject: [PATCH 062/216] build/sage_bootstrap/cmdline.py: Explain default --- build/sage_bootstrap/cmdline.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/sage_bootstrap/cmdline.py b/build/sage_bootstrap/cmdline.py index c62ca6d3a01..3ea6b9b7cb8 100644 --- a/build/sage_bootstrap/cmdline.py +++ b/build/sage_bootstrap/cmdline.py @@ -217,7 +217,7 @@ def make_parser(): type=str, default=[':all-or-nothing:'], nargs='*', help=('package name or designator for all packages of a given type ' '(one of :all:, :standard:, :optional:, and :experimental:); ' - 'default: :all:')) + 'default: :all: (or nothing when --include-dependencies or --exclude-dependencies is given')) parser_list.add_argument( '--has-file', action='append', default=[], metavar='FILENAME', dest='has_files', help=('only include packages that have this file in their metadata directory ' From 1bdb6580c08f39a9affc4ac698a1e8899180fa71 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 6 Oct 2023 15:50:29 -0700 Subject: [PATCH 063/216] .github/workflows/docker.yml: Free more disk space --- .github/workflows/docker.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index d49aa516356..f5ecbf1c056 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -159,7 +159,7 @@ jobs: docker rmi $(docker image ls -aq) echo "Largest packages:" dpkg-query -Wf '${Installed-Size}\t${Package}\n' | sort -n | tail -n 50 - sudo apt-get --fix-broken --yes remove $(dpkg-query -f '${Package}\n' -W | grep -E '^(ghc-|google-cloud-sdk|google-chrome|firefox|mysql-server|dotnet-sdk|hhvm|mono)') || echo "(error ignored)" + sudo apt-get --fix-broken --yes remove $(dpkg-query -f '${Package}\n' -W | grep -E '^(ghc-|google-cloud-sdk|google-chrome|firefox|mysql-server|dotnet-sdk|hhvm|mono|google-cloud-cli|microsoft-edge|azure-cli|temurin|llvm-|powershell|llvm-|r-base|postgresql)') || echo "(error ignored)" df -h if: inputs.free_disk_space - name: Download upstream artifact From 5b9abe5bcec979dd1bd0843e698625fc35e8fb5f Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 8 Oct 2023 13:06:26 -0700 Subject: [PATCH 064/216] .github/workflows/docker.yml: Use https://github.com/marketplace/actions/maximize-build-disk-space --- .github/workflows/docker.yml | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index f5ecbf1c056..a3986899a7d 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -144,24 +144,23 @@ jobs: EXTRA_CONFIGURE_ARGS: --enable-fat-binary EXTRA_SAGE_PACKAGES: ${{ inputs.extra_sage_packages }} steps: + - name: Maximize build disk space + uses: easimon/maximize-build-space@v8 + with: + # need space in /var for Docker images + root-reserve-mb: 40000 + remove-dotnet: true + remove-android: true + remove-haskell: true + remove-codeql: true + remove-docker-images: true + if: inputs.free_disk_space - name: Check out SageMath uses: actions/checkout@v4 with: repository: ${{ inputs.sage_repo }} ref: ${{ inputs.sage_ref }} fetch-depth: 10000 - - name: free disk space - run: | - df -h - sudo swapoff -a - sudo rm -f /swapfile - sudo apt-get clean - docker rmi $(docker image ls -aq) - echo "Largest packages:" - dpkg-query -Wf '${Installed-Size}\t${Package}\n' | sort -n | tail -n 50 - sudo apt-get --fix-broken --yes remove $(dpkg-query -f '${Package}\n' -W | grep -E '^(ghc-|google-cloud-sdk|google-chrome|firefox|mysql-server|dotnet-sdk|hhvm|mono|google-cloud-cli|microsoft-edge|azure-cli|temurin|llvm-|powershell|llvm-|r-base|postgresql)') || echo "(error ignored)" - df -h - if: inputs.free_disk_space - name: Download upstream artifact uses: actions/download-artifact@v3 with: @@ -216,7 +215,10 @@ jobs: .ci/merge-fixes.sh env: GH_TOKEN: ${{ github.token }} - + - name: Show disk space + run: | + df -h + if: inputs.free_disk_space - name: Configure and build Sage distribution within a Docker container run: | set -o pipefail; EXTRA_DOCKER_BUILD_ARGS="--build-arg NUMPROC=4 --build-arg USE_MAKEFLAGS=\"-k V=0 SAGE_NUM_THREADS=3\"" tox -e $TOX_ENV -- $TARGETS 2>&1 | sed "/^configure: notice:/s|^|::warning file=artifacts/$LOGS_ARTIFACT_NAME/config.log::|;/^configure: warning:/s|^|::warning file=artifacts/$LOGS_ARTIFACT_NAME/config.log::|;/^configure: error:/s|^|::error file=artifacts/$LOGS_ARTIFACT_NAME/config.log::|;" From 6127016ec90f4c2f66a99b6e6966cc05df9eeb6c Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 4 Oct 2023 21:23:47 -0700 Subject: [PATCH 065/216] bootstrap-conda: Generate environment files with hard-coded Python minor versions (environment-3.9.yml etc.) This is convenient for conda-lock. Partial cherry-pick from "Use conda-lock for reproducible conda env" --- .devcontainer/onCreate-conda.sh | 2 +- .gitignore | 18 ++++ .gitpod.yml | 2 +- bootstrap-conda | 134 ++++++++++++------------ build/pkgs/matplotlib/distros/conda.txt | 2 +- 5 files changed, 89 insertions(+), 69 deletions(-) diff --git a/.devcontainer/onCreate-conda.sh b/.devcontainer/onCreate-conda.sh index eaa045cd27b..2cbb94e3492 100755 --- a/.devcontainer/onCreate-conda.sh +++ b/.devcontainer/onCreate-conda.sh @@ -4,7 +4,7 @@ set -e # Create conda environment ./bootstrap-conda conda install mamba -n base -c conda-forge -y -mamba env create --file src/environment-dev.yml || mamba env update --file src/environment-dev.yml +mamba env create --file src/environment-dev-3.11.yml || mamba env update --file src/environment-dev-3.11.yml conda init bash # Build sage diff --git a/.gitignore b/.gitignore index 2cec8a0cf62..43f58abcafe 100644 --- a/.gitignore +++ b/.gitignore @@ -27,11 +27,29 @@ # no longer generated, but may still be in user worktrees /src/lib/pkgconfig +# Environment files generated by bootstrap-conda. +# The files without Python version are no longer generated +# but may still be in users' directories. /environment.yml +/environment-3.9.yml +/environment-3.10.yml +/environment-3.11.yml /environment-optional.yml +/environment-optional-3.9.yml +/environment-optional-3.10.yml +/environment-optional-3.11.yml /src/environment.yml +/src/environment-3.9.yml +/src/environment-3.10.yml +/src/environment-3.11.yml /src/environment-dev.yml +/src/environment-dev-3.9.yml +/src/environment-dev-3.10.yml +/src/environment-dev-3.11.yml /src/environment-optional.yml +/src/environment-optional-3.9.yml +/src/environment-optional-3.10.yml +/src/environment-optional-3.11.yml /src/setup.cfg /src/requirements.txt diff --git a/.gitpod.yml b/.gitpod.yml index 52ac8d7184c..51c2687c5d3 100644 --- a/.gitpod.yml +++ b/.gitpod.yml @@ -8,7 +8,7 @@ tasks: # Create conda environment, then configure and build sage init: >- ./bootstrap-conda - && mamba env create --file src/environment-dev.yml --prefix venv + && mamba env create --file src/environment-dev-3.11.yml --prefix venv && conda config --append envs_dirs $(pwd) && conda activate $(pwd)/venv && ./bootstrap diff --git a/bootstrap-conda b/bootstrap-conda index ed4bb9e0d08..811dcbf43b0 100755 --- a/bootstrap-conda +++ b/bootstrap-conda @@ -51,72 +51,74 @@ for PKG_BASE in $(sage-package list --has-file distros/conda.txt --exclude _sage fi done echo >&2 $0:$LINENO: generate conda environment files -( - echo "name: sage-build" - echo "channels:" - echo " - conda-forge" - echo " - nodefaults" - echo "dependencies:" - for pkg in $SYSTEM_PACKAGES; do - echo " - $pkg" - done - echo " # Packages needed for ./bootstrap" - for pkg in $BOOTSTRAP_PACKAGES; do - echo " - $pkg" - done -) > environment.yml +for python_version in 3.9 3.10 3.11; do + ( + echo "name: sage-build" + echo "channels:" + echo " - conda-forge" + echo " - nodefaults" + echo "dependencies:" + echo " - python=$python_version" + for pkg in $SYSTEM_PACKAGES; do + echo " - $pkg" + done + echo " # Packages needed for ./bootstrap" + for pkg in $BOOTSTRAP_PACKAGES; do + echo " - $pkg" + done + ) > environment-$python_version.yml + ( + sed 's/name: sage-build/name: sage/' environment-$python_version.yml + echo " # Additional packages providing all dependencies for the Sage library" + for pkg in $SAGELIB_SYSTEM_PACKAGES; do + echo " - $pkg" + done + ) > src/environment-$python_version.yml -( - sed 's/name: sage-build/name: sage/' environment.yml - echo " # Additional packages providing all dependencies for the Sage library" - for pkg in $SAGELIB_SYSTEM_PACKAGES; do - echo " - $pkg" - done -) > src/environment.yml + ( + cat environment-$python_version.yml + echo " # optional packages" + for pkg in $OPTIONAL_SYSTEM_PACKAGES; do + echo " - $pkg" + done + ) > environment-optional-$python_version.yml -( - sed 's/name: sage/name: sage-dev/' src/environment.yml - echo " # Additional dev tools" - for pkg in $DEVELOP_SYSTEM_PACKAGES; do - echo " - $pkg" - done -) > src/environment-dev.yml - -( - cat environment.yml - echo " # optional packages" - for pkg in $OPTIONAL_SYSTEM_PACKAGES; do - echo " - $pkg" - done -) > environment-optional.yml - -( - cat src/environment.yml - echo " # optional packages" - for pkg in $OPTIONAL_SYSTEM_PACKAGES $SAGELIB_OPTIONAL_SYSTEM_PACKAGES; do - echo " - $pkg" - done -) > src/environment-optional.yml -( - echo >&4 " - pip:" - echo >&5 " - pip:" - for PKG_BASE in $((sage-package list :standard: :optional: --has-file requirements.txt --no-file distros/conda.txt --no-file src; sage-package list :standard: :optional: --has-file install-requires.txt --no-file requirements.txt --no-file distros/conda.txt --no-file src) | sort); do - PKG_SCRIPTS=build/pkgs/$PKG_BASE - SYSTEM_PACKAGES_FILE=$PKG_SCRIPTS/requirements.txt - if [ ! -f $SYSTEM_PACKAGES_FILE ]; then - SYSTEM_PACKAGES_FILE=$PKG_SCRIPTS/install-requires.txt - fi - PKG_TYPE=$(cat $PKG_SCRIPTS/type) - if grep -q SAGERUNTIME $PKG_SCRIPTS/dependencies $PKG_SCRIPTS/dependencies_order_only 2>/dev/null; then - : # cannot install packages that depend on the Sage library - else - case "$PKG_BASE:$PKG_TYPE" in - $DEVELOP_SPKG_PATTERN:*) FD=4;; - *) FD=5;; - esac - ${STRIP_COMMENTS} $SYSTEM_PACKAGES_FILE | while read -r line; do - [ -n "$line" ] && echo >&$FD " - $line" + ( + ( + sed 's/name: sage/name: sage-dev/' src/environment-$python_version.yml + echo " # Additional dev tools" + for pkg in $DEVELOP_SYSTEM_PACKAGES; do + echo " - $pkg" done - fi - done -) 4>> src/environment-dev.yml 5>> src/environment-optional.yml + ) >&4 + ( + cat src/environment-$python_version.yml + echo " # optional packages" + for pkg in $OPTIONAL_SYSTEM_PACKAGES $SAGELIB_OPTIONAL_SYSTEM_PACKAGES; do + echo " - $pkg" + done + ) >&5 + echo >&4 " - pip:" + echo >&5 " - pip:" + for PKG_BASE in $((sage-package list :standard: :optional: --has-file requirements.txt --no-file distros/conda.txt --no-file src; sage-package list :standard: :optional: --has-file install-requires.txt --no-file requirements.txt --no-file distros/conda.txt --no-file src) | sort); do + PKG_SCRIPTS=build/pkgs/$PKG_BASE + SYSTEM_PACKAGES_FILE=$PKG_SCRIPTS/requirements.txt + if [ ! -f $SYSTEM_PACKAGES_FILE ]; then + SYSTEM_PACKAGES_FILE=$PKG_SCRIPTS/install-requires.txt + fi + PKG_TYPE=$(cat $PKG_SCRIPTS/type) + if grep -q SAGERUNTIME $PKG_SCRIPTS/dependencies $PKG_SCRIPTS/dependencies_order_only 2>/dev/null; then + : # cannot install packages that depend on the Sage library + else + case "$PKG_BASE:$PKG_TYPE" in + $DEVELOP_SPKG_PATTERN:*) FD=4;; + *:standard) FD="4 5";; + *) FD=5;; + esac + ${STRIP_COMMENTS} $SYSTEM_PACKAGES_FILE | while read -r line; do + [ -n "$line" ] && for fd in $FD; do echo >&$fd " - $line"; done + done + fi + done + ) 4>> src/environment-dev-$python_version.yml 5>> src/environment-optional-$python_version.yml +done diff --git a/build/pkgs/matplotlib/distros/conda.txt b/build/pkgs/matplotlib/distros/conda.txt index 8b3901c7c9a..9fdcdfeb47f 100644 --- a/build/pkgs/matplotlib/distros/conda.txt +++ b/build/pkgs/matplotlib/distros/conda.txt @@ -1,2 +1,2 @@ # Trac #33642: For unknown reasons, without the version constraint, conda installs only 3.3.2 -"matplotlib>=3.5.1" +matplotlib>=3.5.1 From 03a2acfeade61d5bc57c1bfb79be802b8b10b7f2 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 8 Oct 2023 13:07:57 -0700 Subject: [PATCH 066/216] src/doc/en/installation/conda.rst: Update for versioned environment-... files --- src/doc/en/installation/conda.rst | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/src/doc/en/installation/conda.rst b/src/doc/en/installation/conda.rst index 6b4cb871dd7..14fe52ad2e2 100644 --- a/src/doc/en/installation/conda.rst +++ b/src/doc/en/installation/conda.rst @@ -75,13 +75,16 @@ 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 --name sage-build + $ conda env create --file environment-3.11.yml --name sage-build $ conda activate sage-build - Alternatively, use ``environment-optional.yml`` in place of + Alternatively, use ``environment-optional-3.11.yml`` in place of ``environment.yml`` to create an environment with all standard and optional packages recognized by sage. + A different Python version can be selected by replacing ``3.11`` by ``3.9`` + or ``3.10`` in these commands. + - Then the SageMath distribution will be built using the compilers provided by Conda and using many packages installed by Conda:: @@ -123,16 +126,15 @@ 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 --name sage-dev + $ mamba env create --file src/environment-dev-3.11.yml --name sage-dev $ conda activate sage-dev - Alternatively, you can use ``src/environment.yml`` or - ``src/environment-optional.yml``, which will only install standard + Alternatively, you can use ``src/environment-3.11.yml`` or + ``src/environment-optional-3.11.yml``, which will only install standard (and optional) packages without any additional developer tools. - 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 select another Python version (here 3.9). + A different Python version can be selected by replacing ``3.11`` by ``3.9`` + or ``3.10`` in these commands. - Install the build prerequisites and the Sage library:: @@ -142,7 +144,7 @@ Here we assume that you are using a git checkout. - Verify that Sage has been installed:: $ sage -c 'print(version())' - SageMath version 9.6.beta5, Release Date: 2022-03-12 + SageMath version 10.2.beta4, Release Date: 2023-09-24 Note that ``make`` is not used at all. All dependencies (including all Python packages) are provided by conda. @@ -162,7 +164,7 @@ After editing any Cython files, rebuild the Sage library using:: In order to update the conda environment later, you can run:: - $ mamba env update --file src/environment-dev.yml --name sage-dev + $ mamba env update --file src/environment-dev-3.11.yml --name sage-dev To build the documentation, use:: From 5c0bac856fb04cf589209ca5059a02f121e4b3ff Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 27 Sep 2023 12:37:35 -0700 Subject: [PATCH 067/216] bootstrap, Makefile (bootstrap-clean): Update for versioned environment-... files --- Makefile | 6 +----- bootstrap | 8 ++++---- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/Makefile b/Makefile index 11a7b77665a..ae90db4e9e2 100644 --- a/Makefile +++ b/Makefile @@ -158,11 +158,7 @@ bootstrap-clean: rm -rf config/install-sh config/compile config/config.guess config/config.sub config/missing configure build/make/Makefile-auto.in rm -f src/doc/en/installation/*.txt rm -rf src/doc/en/reference/spkg/*.rst - rm -f environment.yml - rm -f src/environment.yml - rm -f src/environment-dev.yml - rm -f environment-optional.yml - rm -f src/environment-optional.yml + for a in environment environment-optional src/environment src/environment-dev src/environment-optional; do rm -f $$a.yml $$a-3.[89].yml $$a-3.1[0-9].yml; done rm -f src/Pipfile rm -f src/pyproject.toml rm -f src/requirements.txt diff --git a/bootstrap b/bootstrap index 54d0a156239..2ae99949025 100755 --- a/bootstrap +++ b/bootstrap @@ -226,10 +226,10 @@ save () { build/make/Makefile-auto.in \ src/doc/en/installation/*.txt \ src/doc/en/reference/spkg/*.rst \ - environment.yml \ - src/environment.yml \ - environment-optional.yml \ - src/environment-optional.yml \ + environment-3.[89].yml environment-3.1[0-9].yml \ + src/environment-3.[89].yml src/environment-3.1[0-9].yml \ + environment-optional-3.[89].yml environment-optional-3.1[0-9].yml \ + src/environment-optional-3.[89].yml src/environment-optional-3.1[0-9].yml \ src/Pipfile \ src/pyproject.toml \ src/requirements.txt \ From c2be172347daec2c6c292e248eb598b406776577 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 27 Sep 2023 12:43:59 -0700 Subject: [PATCH 068/216] tox.ini (local-conda-environment): Update for versioned environment-... files --- tox.ini | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/tox.ini b/tox.ini index c084e4c821e..9e124a281a6 100644 --- a/tox.ini +++ b/tox.ini @@ -527,9 +527,14 @@ setenv = local-conda-miniconda: CONDA_INSTALLER_FILE=Miniconda3-latest-{env:CONDA_OS}-x86_64.sh local-conda: SETENV=. {env:CONDA_PREFIX}/bin/activate base local-conda-environment: CONDA_SAGE_ENVIRONMENT=sage-build - local-conda-environment: CONDA_SAGE_ENVIRONMENT_FILE=environment.yml - local-conda-environment-optional: CONDA_SAGE_ENVIRONMENT_FILE=environment-optional.yml + local-conda-environment: CONDA_SAGE_ENVIRONMENT_DIR= + local-conda-environment-src: CONDA_SAGE_ENVIRONMENT=sage local-conda-environment-src: CONDA_SAGE_ENVIRONMENT_DIR=src/ + local-conda-environment: CONDA_SAGE_ENVIRONMENT_FILE=environment-{env:PYTHON_MAJOR}.{env:PYTHON_MINOR}.yml + local-conda-environment-optional: CONDA_SAGE_ENVIRONMENT_FILE=environment-optional-{env:PYTHON_MAJOR}.{env:PYTHON_MINOR}.yml + local-conda-environment-dev: CONDA_SAGE_ENVIRONMENT=sage-dev + local-conda-environment-dev: CONDA_SAGE_ENVIRONMENT_DIR=src/ + local-conda-environment-dev: CONDA_SAGE_ENVIRONMENT_FILE=environment-dev-{env:PYTHON_MAJOR}.{env:PYTHON_MINOR}.yml local-conda-environment: SETENV_CONFIGURE=( {env:CONDA_PREFIX}/bin/conda env create -n {env:CONDA_SAGE_ENVIRONMENT} --file {env:CONDA_SAGE_ENVIRONMENT_DIR:}{env:CONDA_SAGE_ENVIRONMENT_FILE} || {env:CONDA_PREFIX}/bin/conda env update -n {env:CONDA_SAGE_ENVIRONMENT} --file {env:CONDA_SAGE_ENVIRONMENT_DIR:}{env:CONDA_SAGE_ENVIRONMENT_FILE} ) && . {env:CONDA_PREFIX}/bin/activate {env:CONDA_SAGE_ENVIRONMENT} # # Configuration factors From b3ba591faf23946ff7bdd777a8c865bd474f039c Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 27 Sep 2023 13:17:26 -0700 Subject: [PATCH 069/216] .github/workflows/ci-conda.yml: Update for versioned environment*.yml --- .github/workflows/ci-conda.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci-conda.yml b/.github/workflows/ci-conda.yml index 75babf3ab8c..231f0572f75 100644 --- a/.github/workflows/ci-conda.yml +++ b/.github/workflows/ci-conda.yml @@ -59,7 +59,7 @@ jobs: with: path: ~/conda_pkgs_dir key: - ${{ runner.os }}-conda-${{ hashFiles('src/environment.yml') }} + ${{ runner.os }}-conda-${{ hashFiles('src/environment-3.11.yml') }} - name: Setup Conda uses: conda-incubator/setup-miniconda@v2 @@ -69,7 +69,7 @@ jobs: channels: conda-forge,defaults channel-priority: true activate-environment: sage-build - environment-file: src/${{ matrix.conda-env }}.yml + environment-file: src/${{ matrix.conda-env }}-${{ matrix.python }}.yml - name: Print Conda environment shell: bash -l {0} From 018de2b76b3fefb561460e3feef3a69fa1c5e3be Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 3 Oct 2023 15:47:29 -0700 Subject: [PATCH 070/216] .github/workflows/ci-conda.yml: Fix environment name --- .github/workflows/ci-conda.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci-conda.yml b/.github/workflows/ci-conda.yml index 231f0572f75..81ab9fe3a61 100644 --- a/.github/workflows/ci-conda.yml +++ b/.github/workflows/ci-conda.yml @@ -68,7 +68,7 @@ jobs: mamba-version: "*" channels: conda-forge,defaults channel-priority: true - activate-environment: sage-build + activate-environment: sage environment-file: src/${{ matrix.conda-env }}-${{ matrix.python }}.yml - name: Print Conda environment From fc9bab5e35bf54388d9f5edd5e9e0d9668d4755c Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 27 Sep 2023 14:01:14 -0700 Subject: [PATCH 071/216] tox.ini (conda-environment-{src,dev}), .github/workflows/ci-conda.yml: Use configure --enable-system-site-packages --- .github/workflows/ci-conda.yml | 2 +- tox.ini | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci-conda.yml b/.github/workflows/ci-conda.yml index 81ab9fe3a61..e520fa17104 100644 --- a/.github/workflows/ci-conda.yml +++ b/.github/workflows/ci-conda.yml @@ -83,7 +83,7 @@ jobs: run: | ./bootstrap echo "::add-matcher::.github/workflows/configure-systempackage-problem-matcher.json" - ./configure --enable-build-as-root --with-python=$CONDA_PREFIX/bin/python --prefix=$CONDA_PREFIX $(for pkg in $(./sage -package list :standard: --has-file spkg-configure.m4 --has-file distros/conda.txt --exclude rpy2); do echo --with-system-$pkg=force; done) + ./configure --enable-build-as-root --with-python=$CONDA_PREFIX/bin/python --prefix=$CONDA_PREFIX --enable-system-site-packages $(for pkg in $(./sage -package list :standard: --has-file spkg-configure.m4 --has-file distros/conda.txt --exclude rpy2); do echo --with-system-$pkg=force; done) echo "::remove-matcher owner=configure-system-package-warning::" echo "::remove-matcher owner=configure-system-package-error::" diff --git a/tox.ini b/tox.ini index 9e124a281a6..0f4540605e2 100644 --- a/tox.ini +++ b/tox.ini @@ -191,6 +191,7 @@ setenv = sitepackages: ENABLE_SYSTEM_SITE_PACKAGES=yes sitepackages: CONFIG_CONFIGURE_ARGS_SITEPACKAGES=--enable-system-site-packages conda-environment: SAGE_PACKAGE_LIST_ARGS=_prereq + conda-environment-{src,dev}: CONFIG_CONFIGURE_ARGS_SITEPACKAGES=--enable-system-site-packages # Whether to add the system packages needed for bootstrapping EXTRA_SAGE_PACKAGES_0=_bootstrap nobootstrap: EXTRA_SAGE_PACKAGES_0= From b02ef8eb62678bde34550ab1eb9ed8458ed9b099 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 4 Oct 2023 21:24:22 -0700 Subject: [PATCH 072/216] bootstrap-conda: Refactor using sage-get-system-packages --- bootstrap-conda | 90 +++++++++++++++++++++++++++++++++---------------- 1 file changed, 61 insertions(+), 29 deletions(-) diff --git a/bootstrap-conda b/bootstrap-conda index 811dcbf43b0..90d27ab7be7 100755 --- a/bootstrap-conda +++ b/bootstrap-conda @@ -11,45 +11,75 @@ STRIP_COMMENTS="sed s/#.*//;" shopt -s extglob DEVELOP_SPKG_PATTERN="@(_develop$(for a in $(head -n 1 build/pkgs/_develop/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= -DEVELOP_SYSTEM_PACKAGES= +BOOTSTRAP_PACKAGES=_bootstrap +PACKAGES= +OPTIONAL_PACKAGES= +SAGELIB_PACKAGES= +SAGELIB_OPTIONAL_PACKAGES= +DEVELOP_PACKAGES= + for PKG_BASE in $(sage-package list --has-file distros/conda.txt --exclude _sagemath); 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 [ -n "$PKG_SYSTEM_PACKAGES" ]; then if [ -f $PKG_SCRIPTS/spkg-configure.m4 ]; then + if grep -q SAGE_PYTHON_PACKAGE_CHECK $PKG_SCRIPTS/spkg-configure.m4; then + # Python package that would need --enable-system-site-packages to be used + # with the Sage distribution, but we do not recommend that for conda. + PKG_SAGELIB_ONLY=yes + else + PKG_SAGELIB_ONLY=no + fi + else + # No spkg-configure, so the Sage distribution is not able to make use of this package. + PKG_SAGELIB_ONLY=yes + fi + [ -n "$BOOTSTRAP_VERBOSE" ] && echo "$PKG_BASE:$PKG_TYPE:$PKG_SAGELIB_ONLY" + if [ $PKG_SAGELIB_ONLY = no ]; then case "$PKG_BASE:$PKG_TYPE" in *:standard) - SYSTEM_PACKAGES+=" $PKG_SYSTEM_PACKAGES" + PACKAGES+=" $PKG_BASE" ;; $DEVELOP_SPKG_PATTERN:*) - DEVELOP_SYSTEM_PACKAGES+=" $PKG_SYSTEM_PACKAGES" + DEVELOP_PACKAGES+=" $PKG_BASE" ;; *) - OPTIONAL_SYSTEM_PACKAGES+=" $PKG_SYSTEM_PACKAGES" + OPTIONAL_PACKAGES+=" $PKG_BASE" ;; esac else case "$PKG_BASE:$PKG_TYPE" in *:standard) - SAGELIB_SYSTEM_PACKAGES+=" $PKG_SYSTEM_PACKAGES" + SAGELIB_PACKAGES+=" $PKG_BASE" ;; $DEVELOP_SPKG_PATTERN:*) - DEVELOP_SYSTEM_PACKAGES+=" $PKG_SYSTEM_PACKAGES" + DEVELOP_PACKAGES+=" $PKG_BASE" ;; *) - SAGELIB_OPTIONAL_SYSTEM_PACKAGES+=" $PKG_SYSTEM_PACKAGES" + SAGELIB_OPTIONAL_PACKAGES+=" $PKG_BASE" ;; esac fi fi done +unset PKG_SYSTEM_PACKAGES + +[ -n "$BOOTSTRAP_VERBOSE" ] && echo "## Collected:" && set | grep PACKAGES= + +# Translate to system packages +export ENABLE_SYSTEM_SITE_PACKAGES=yes # Disable filtering in sage-get-system-packages +SYSTEM_PACKAGES=$(sage-get-system-packages conda $PACKAGES) +BOOTSTRAP_SYSTEM_PACKAGES=$(sage-get-system-packages conda $BOOTSTRAP_PACKAGES) +OPTIONAL_SYSTEM_PACKAGES=$(sage-get-system-packages conda $OPTIONAL_PACKAGES) +SAGELIB_SYSTEM_PACKAGES=$(sage-get-system-packages conda $SAGELIB_PACKAGES) +SAGELIB_OPTIONAL_SYSTEM_PACKAGES=$(sage-get-system-packages conda $SAGELIB_OPTIONAL_PACKAGES) +DEVELOP_SYSTEM_PACKAGES=$(sage-get-system-packages conda $DEVELOP_PACKAGES) +unset ENABLE_SYSTEM_SITE_PACKAGES + +[ -n "$BOOTSTRAP_VERBOSE" ] && echo "## Translated to system:" && set | grep SYSTEM_PACKAGES= + echo >&2 $0:$LINENO: generate conda environment files for python_version in 3.9 3.10 3.11; do ( @@ -63,7 +93,7 @@ for python_version in 3.9 3.10 3.11; do echo " - $pkg" done echo " # Packages needed for ./bootstrap" - for pkg in $BOOTSTRAP_PACKAGES; do + for pkg in $BOOTSTRAP_SYSTEM_PACKAGES; do echo " - $pkg" done ) > environment-$python_version.yml @@ -84,23 +114,25 @@ for python_version in 3.9 3.10 3.11; do ) > environment-optional-$python_version.yml ( - ( - sed 's/name: sage/name: sage-dev/' src/environment-$python_version.yml - echo " # Additional dev tools" - for pkg in $DEVELOP_SYSTEM_PACKAGES; do - echo " - $pkg" - done - ) >&4 - ( - cat src/environment-$python_version.yml - echo " # optional packages" - for pkg in $OPTIONAL_SYSTEM_PACKAGES $SAGELIB_OPTIONAL_SYSTEM_PACKAGES; do - echo " - $pkg" - done - ) >&5 + sed 's/name: sage/name: sage-dev/' src/environment-$python_version.yml + echo " # Additional dev tools" + for pkg in $DEVELOP_SYSTEM_PACKAGES; do + echo " - $pkg" + done + ) > src/environment-dev-$python_version.yml + + ( + cat src/environment-$python_version.yml + echo " # optional packages" + for pkg in $OPTIONAL_SYSTEM_PACKAGES $SAGELIB_OPTIONAL_SYSTEM_PACKAGES; do + echo " - $pkg" + done + ) > src/environment-optional-$python_version.yml + + ( echo >&4 " - pip:" echo >&5 " - pip:" - for PKG_BASE in $((sage-package list :standard: :optional: --has-file requirements.txt --no-file distros/conda.txt --no-file src; sage-package list :standard: :optional: --has-file install-requires.txt --no-file requirements.txt --no-file distros/conda.txt --no-file src) | sort); do + for PKG_BASE in $(sage-package list :standard: :optional: --has-file requirements.txt --no-file distros/conda.txt --no-file src; sage-package list :standard: :optional: --has-file install-requires.txt --no-file requirements.txt --no-file distros/conda.txt --no-file src); do PKG_SCRIPTS=build/pkgs/$PKG_BASE SYSTEM_PACKAGES_FILE=$PKG_SCRIPTS/requirements.txt if [ ! -f $SYSTEM_PACKAGES_FILE ]; then From 92088d32521fca1dc70c078c44514e1353fcfaf7 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 8 Oct 2023 13:09:38 -0700 Subject: [PATCH 073/216] py312: fix AttributeError doctests (sed changes) In python 3.12, attribute errors add a suggestion at the end of the usual error message ("Did you mean ...?"). We add ... at the end of these doctest outputs to fix it. This commit has the bulk of the changes, obtained with: git grep -l "AttributeError:" src | xargs sed -ie \ 's/^ *\(AttributeError: .*\)\?has no attribute.*$/&.../' --- .../coercion_and_categories.rst | 2 +- .../tutorial-objects-and-classes.rst | 4 +-- src/sage/algebras/cluster_algebra.py | 2 +- .../weyl_lie_conformal_algebra.py | 2 +- .../algebras/steenrod/steenrod_algebra.py | 2 +- src/sage/categories/category.py | 2 +- src/sage/categories/category_with_axiom.py | 4 +-- src/sage/categories/enumerated_sets.py | 6 ++-- src/sage/categories/examples/sets_cat.py | 2 +- src/sage/categories/homset.py | 2 +- src/sage/categories/modules_with_basis.py | 2 +- src/sage/categories/monoids.py | 2 +- src/sage/combinat/finite_state_machine.py | 2 +- src/sage/combinat/growth.py | 2 +- src/sage/combinat/integer_lists/lists.py | 2 +- src/sage/combinat/posets/posets.py | 2 +- src/sage/cpython/debug.pyx | 2 +- src/sage/cpython/getattr.pyx | 22 +++++++------- src/sage/crypto/classical.py | 8 ++--- .../crypto/mq/mpolynomialsystemgenerator.py | 2 +- src/sage/data_structures/bitset.pyx | 8 ++--- src/sage/doctest/reporting.py | 2 +- src/sage/dynamics/finite_dynamical_system.py | 4 +-- src/sage/geometry/cone.py | 2 +- src/sage/geometry/fan.py | 2 +- .../face_iterator.pyx | 2 +- src/sage/geometry/toric_plotter.py | 2 +- .../groups/matrix_gps/finitely_generated.py | 2 +- src/sage/homology/chains.py | 10 +++---- src/sage/homology/free_resolution.py | 2 +- src/sage/interfaces/magma.py | 2 +- src/sage/libs/gap/element.pyx | 2 +- src/sage/manifolds/calculus_method.py | 2 +- .../differentiable/vectorfield_module.py | 2 +- src/sage/matrix/matrix2.pyx | 2 +- src/sage/matrix/matrix_cyclo_dense.pyx | 2 +- src/sage/matrix/matrix_gfpn_dense.pyx | 2 +- src/sage/matrix/matrix_space.py | 2 +- src/sage/matroids/linear_matroid.pyx | 2 +- src/sage/misc/functional.py | 2 +- src/sage/misc/instancedoc.pyx | 2 +- src/sage/misc/lazy_attribute.pyx | 14 ++++----- src/sage/misc/object_multiplexer.py | 2 +- src/sage/misc/sage_input.py | 4 +-- src/sage/modules/fp_graded/steenrod/module.py | 2 +- src/sage/parallel/map_reduce.py | 2 +- src/sage/plot/colors.py | 4 +-- src/sage/rings/asymptotic/asymptotic_ring.py | 2 +- src/sage/rings/asymptotic/growth_group.py | 2 +- src/sage/rings/ideal.py | 2 +- src/sage/rings/number_field/number_field.py | 8 ++--- src/sage/rings/padics/generic_nodes.py | 2 +- .../rings/polynomial/polynomial_element.pyx | 4 +-- .../polynomial/polynomial_quotient_ring.py | 2 +- src/sage/rings/ring.pyx | 2 +- src/sage/schemes/toric/morphism.py | 2 +- .../sets/disjoint_union_enumerated_sets.py | 2 +- src/sage/sets/set.py | 2 +- src/sage/structure/category_object.pyx | 2 +- src/sage/structure/element.pyx | 30 +++++++++---------- src/sage/structure/sequence.py | 4 +-- src/sage/symbolic/pynac_impl.pxi | 2 +- 62 files changed, 114 insertions(+), 114 deletions(-) diff --git a/src/doc/en/thematic_tutorials/coercion_and_categories.rst b/src/doc/en/thematic_tutorials/coercion_and_categories.rst index bb23331c151..7f5712caea7 100644 --- a/src/doc/en/thematic_tutorials/coercion_and_categories.rst +++ b/src/doc/en/thematic_tutorials/coercion_and_categories.rst @@ -1223,7 +1223,7 @@ However, only "elementary" construction functors have a rank:: sage: (Fract*Poly).rank Traceback (most recent call last): ... - AttributeError: 'CompositeConstructionFunctor' object has no attribute 'rank' + AttributeError: 'CompositeConstructionFunctor' object has no attribute 'rank'... .. end of output diff --git a/src/doc/en/thematic_tutorials/tutorial-objects-and-classes.rst b/src/doc/en/thematic_tutorials/tutorial-objects-and-classes.rst index 553a946c4d8..3cd71a9bad4 100644 --- a/src/doc/en/thematic_tutorials/tutorial-objects-and-classes.rst +++ b/src/doc/en/thematic_tutorials/tutorial-objects-and-classes.rst @@ -318,7 +318,7 @@ http://docs.python.org/library/ for a complete list. :: sage: e.__dict__ Traceback (most recent call last): ... - AttributeError: 'sage.rings.integer.Integer' object has no attribute '__dict__' + AttributeError: 'sage.rings.integer.Integer' object has no attribute '__dict__'... sage: id4 = SymmetricGroup(4).one() sage: type(id4) @@ -326,7 +326,7 @@ http://docs.python.org/library/ for a complete list. :: sage: id4.__dict__ Traceback (most recent call last): ... - AttributeError: 'sage.groups.perm_gps.permgroup_element.SymmetricGroupElement' object has no attribute '__dict__' + AttributeError: 'sage.groups.perm_gps.permgroup_element.SymmetricGroupElement' object has no attribute '__dict__'... .. note:: diff --git a/src/sage/algebras/cluster_algebra.py b/src/sage/algebras/cluster_algebra.py index b72d2a12976..14669dfed5c 100644 --- a/src/sage/algebras/cluster_algebra.py +++ b/src/sage/algebras/cluster_algebra.py @@ -167,7 +167,7 @@ sage: (t*s).g_vector() Traceback (most recent call last): ... - AttributeError: 'ClusterAlgebra_with_category.element_class' object has no attribute 'g_vector' + AttributeError: 'ClusterAlgebra_with_category.element_class' object has no attribute 'g_vector'... sage: A = ClusterAlgebra(['A', 2], principal_coefficients=True) sage: A.explore_to_depth(infinity) sage: s = A.cluster_variable((0, -1)); s diff --git a/src/sage/algebras/lie_conformal_algebras/weyl_lie_conformal_algebra.py b/src/sage/algebras/lie_conformal_algebras/weyl_lie_conformal_algebra.py index e4a91723558..343ee8a66f9 100644 --- a/src/sage/algebras/lie_conformal_algebras/weyl_lie_conformal_algebra.py +++ b/src/sage/algebras/lie_conformal_algebras/weyl_lie_conformal_algebra.py @@ -109,7 +109,7 @@ class WeylLieConformalAlgebra(LieConformalAlgebraWithStructureCoefficients): sage: alpha0.degree() Traceback (most recent call last): ... - AttributeError: 'WeylLieConformalAlgebra_with_category.element_class' object has no attribute 'degree' + AttributeError: 'WeylLieConformalAlgebra_with_category.element_class' object has no attribute 'degree'... TESTS:: diff --git a/src/sage/algebras/steenrod/steenrod_algebra.py b/src/sage/algebras/steenrod/steenrod_algebra.py index 978a3557a9d..7c4d444f81c 100644 --- a/src/sage/algebras/steenrod/steenrod_algebra.py +++ b/src/sage/algebras/steenrod/steenrod_algebra.py @@ -1080,7 +1080,7 @@ def homogeneous_component(self, n): sage: a.antipode() # not defined Traceback (most recent call last): ... - AttributeError: 'CombinatorialFreeModule_with_category.element_class' object has no attribute 'antipode' + AttributeError: 'CombinatorialFreeModule_with_category.element_class' object has no attribute 'antipode'... sage: A(a).antipode() # convert to elt of A, then compute antipode Sq(2,1) + Sq(5) diff --git a/src/sage/categories/category.py b/src/sage/categories/category.py index 57ef7f4184b..29bce8ee415 100644 --- a/src/sage/categories/category.py +++ b/src/sage/categories/category.py @@ -2129,7 +2129,7 @@ def _with_axioms(self, axioms): sage: Semigroups().Inverse() Traceback (most recent call last): ... - AttributeError: 'Semigroups_with_category' object has no attribute 'Inverse' + AttributeError: 'Semigroups_with_category' object has no attribute 'Inverse'... sage: Semigroups()._with_axioms(["Inverse"]) Category of semigroups diff --git a/src/sage/categories/category_with_axiom.py b/src/sage/categories/category_with_axiom.py index 5227792e725..4775d4e5bf1 100644 --- a/src/sage/categories/category_with_axiom.py +++ b/src/sage/categories/category_with_axiom.py @@ -554,7 +554,7 @@ class from the base category class:: sage: Magmas.Unital.Associative Traceback (most recent call last): ... - AttributeError: type object 'Magmas.Unital' has no attribute 'Associative' + AttributeError: type object 'Magmas.Unital' has no attribute 'Associative'... The purpose of this section is to explain the design of the code layout and the rationale for this mismatch. @@ -769,7 +769,7 @@ def _(): return LazyImport('sage.categories.rngs', 'Rngs', at_startup=True) sage: Semirings().NoZeroDivisors() Traceback (most recent call last): ... - AttributeError: 'Semirings_with_category' object has no attribute 'NoZeroDivisors' + AttributeError: 'Semirings_with_category' object has no attribute 'NoZeroDivisors'... Concretely, this is to be implemented by defining the new axiom in the (``SubcategoryMethods`` nested class of the) appropriate category with diff --git a/src/sage/categories/enumerated_sets.py b/src/sage/categories/enumerated_sets.py index a8bea53f907..b0ea05d0563 100644 --- a/src/sage/categories/enumerated_sets.py +++ b/src/sage/categories/enumerated_sets.py @@ -610,7 +610,7 @@ def _list_from_iterator(self): sage: (QQ^2).list() # indirect test # needs sage.modules Traceback (most recent call last): ... - AttributeError: 'FreeModule_ambient_field_with_category' object has no attribute 'list' + AttributeError: 'FreeModule_ambient_field_with_category' object has no attribute 'list'... Here we test that for an object that does not know whether it is finite or not. Calling ``x.list()`` simply tries to create @@ -622,11 +622,11 @@ def _list_from_iterator(self): sage: Q.is_finite() Traceback (most recent call last): ... - AttributeError: 'QuotientRing_generic_with_category' object has no attribute 'is_finite' + AttributeError: 'QuotientRing_generic_with_category' object has no attribute 'is_finite'... sage: Q.list() # indirect test Traceback (most recent call last): ... - AttributeError: 'QuotientRing_generic_with_category' object has no attribute 'list' + AttributeError: 'QuotientRing_generic_with_category' object has no attribute 'list'... Here is another example. We artificially create a version of the ring of integers that does not know whether it is finite diff --git a/src/sage/categories/examples/sets_cat.py b/src/sage/categories/examples/sets_cat.py index e0853d63f94..fbadb9ca405 100644 --- a/src/sage/categories/examples/sets_cat.py +++ b/src/sage/categories/examples/sets_cat.py @@ -619,7 +619,7 @@ class PrimeNumbers_Facade(PrimeNumbers_Abstract): sage: pf.next() Traceback (most recent call last): ... - AttributeError: 'sage.rings.integer.Integer' object has no attribute 'next' + AttributeError: 'sage.rings.integer.Integer' object has no attribute 'next'... unlike in the other implementations:: diff --git a/src/sage/categories/homset.py b/src/sage/categories/homset.py index 22ba9d047fc..2a8b8aeedeb 100644 --- a/src/sage/categories/homset.py +++ b/src/sage/categories/homset.py @@ -632,7 +632,7 @@ def __init__(self, X, Y, category=None, base=None, check=True): sage: H = MyHomset(X, Y, category=1, base = ZZ, check = False) Traceback (most recent call last): ... - AttributeError: 'sage.rings.integer.Integer' object has no attribute 'Homsets' + AttributeError: 'sage.rings.integer.Integer' object has no attribute 'Homsets'... sage: P. = ZZ[] sage: f = P.hom([1/2*t]) sage: f.parent().domain() diff --git a/src/sage/categories/modules_with_basis.py b/src/sage/categories/modules_with_basis.py index e97bf851388..c4933d0657f 100644 --- a/src/sage/categories/modules_with_basis.py +++ b/src/sage/categories/modules_with_basis.py @@ -2456,7 +2456,7 @@ def apply_multilinear_morphism(self, f, codomain=None): sage: tensor([a, b]).apply_multilinear_morphism(f) # needs sage.modules Traceback (most recent call last): ... - AttributeError: 'int' object has no attribute 'parent' + AttributeError: 'int' object has no attribute 'parent'... Here we consider an example where the codomain is a module with basis with a different base ring:: diff --git a/src/sage/categories/monoids.py b/src/sage/categories/monoids.py index 38dd7248c9d..28474bd17b6 100644 --- a/src/sage/categories/monoids.py +++ b/src/sage/categories/monoids.py @@ -556,7 +556,7 @@ def algebra_generators(self): Traceback (most recent call last): ... AttributeError: 'IntegerModMonoid_with_category' object - has no attribute 'monoid_generators' + has no attribute 'monoid_generators'... sage: Z12.semigroup_generators() Family (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11) sage: Z12.algebra(QQ).algebra_generators() # needs sage.modules diff --git a/src/sage/combinat/finite_state_machine.py b/src/sage/combinat/finite_state_machine.py index 9a1d4bb892c..acd0adb2718 100644 --- a/src/sage/combinat/finite_state_machine.py +++ b/src/sage/combinat/finite_state_machine.py @@ -1835,7 +1835,7 @@ def __getstate__(self): sage: T1.transitions Traceback (most recent call last): ... - AttributeError: 'FSMState' object has no attribute 'transitions' + AttributeError: 'FSMState' object has no attribute 'transitions'... sage: A1 = loads(dumps(A)) sage: all(A.state(j) == A1.state(j) for j in [0, 1]) True diff --git a/src/sage/combinat/growth.py b/src/sage/combinat/growth.py index 86d5070a590..23b7a279fdc 100644 --- a/src/sage/combinat/growth.py +++ b/src/sage/combinat/growth.py @@ -371,7 +371,7 @@ sage: GrowthDiagram(RulePascal(), [3,1,2]) Traceback (most recent call last): ... - AttributeError: 'RulePascal' object has no attribute 'forward_rule' + AttributeError: 'RulePascal' object has no attribute 'forward_rule'... We now re-implement the rule where we provide the dual graded graphs:: diff --git a/src/sage/combinat/integer_lists/lists.py b/src/sage/combinat/integer_lists/lists.py index 5143e5cb5e8..9117a6076f7 100644 --- a/src/sage/combinat/integer_lists/lists.py +++ b/src/sage/combinat/integer_lists/lists.py @@ -261,7 +261,7 @@ def __getattr__(self, name): sage: L.foo Traceback (most recent call last): ... - AttributeError: 'NoneType' object has no attribute 'foo' + AttributeError: 'NoneType' object has no attribute 'foo'... """ return getattr(self.backend, name) diff --git a/src/sage/combinat/posets/posets.py b/src/sage/combinat/posets/posets.py index 0963c2b9d31..d3c46a1daf7 100644 --- a/src/sage/combinat/posets/posets.py +++ b/src/sage/combinat/posets/posets.py @@ -8825,7 +8825,7 @@ def is_induced_subposet(self, other): sage: Poset().is_induced_subposet('junk') Traceback (most recent call last): ... - AttributeError: 'str' object has no attribute 'subposet' + AttributeError: 'str' object has no attribute 'subposet'... """ if (not self._is_facade or (isinstance(other, FinitePoset) and not other._is_facade)): diff --git a/src/sage/cpython/debug.pyx b/src/sage/cpython/debug.pyx index 986abff2a99..022d8e1fed7 100644 --- a/src/sage/cpython/debug.pyx +++ b/src/sage/cpython/debug.pyx @@ -123,7 +123,7 @@ def getattr_debug(obj, name, default=_no_default): sage: _ = getattr_debug(1, "foo") Traceback (most recent call last): ... - AttributeError: 'sage.rings.integer.Integer' object has no attribute 'foo' + AttributeError: 'sage.rings.integer.Integer' object has no attribute 'foo'... sage: _ = getattr_debug(1, "foo", "xyz") getattr_debug(obj=1, name='foo'): type(obj) = diff --git a/src/sage/cpython/getattr.pyx b/src/sage/cpython/getattr.pyx index 52afed49d64..1f49e5230c3 100644 --- a/src/sage/cpython/getattr.pyx +++ b/src/sage/cpython/getattr.pyx @@ -53,12 +53,12 @@ cdef class AttributeErrorMessage: sage: 1.bla #indirect doctest Traceback (most recent call last): ... - AttributeError: 'sage.rings.integer.Integer' object has no attribute 'bla' + AttributeError: 'sage.rings.integer.Integer' object has no attribute 'bla'... sage: x = polygen(ZZ, 'x') sage: QQ[x].gen().bla # needs sage.libs.flint Traceback (most recent call last): ... - AttributeError: 'sage.rings.polynomial.polynomial_rational_flint.Polynomial_rational_flint' object has no attribute 'bla' + AttributeError: 'sage.rings.polynomial.polynomial_rational_flint.Polynomial_rational_flint' object has no attribute 'bla'... :: @@ -144,7 +144,7 @@ cpdef raw_getattr(obj, name): sage: raw_getattr(X, "attr") Traceback (most recent call last): ... - AttributeError: '...' object has no attribute 'attr' + AttributeError: '...' object has no attribute 'attr'... sage: x = X() sage: raw_getattr(x, "prop") @@ -173,7 +173,7 @@ cpdef raw_getattr(obj, name): sage: raw_getattr(Y, "attr") Traceback (most recent call last): ... - AttributeError: '...' object has no attribute 'attr' + AttributeError: '...' object has no attribute 'attr'... sage: y = Y() sage: raw_getattr(y, "prop") @@ -278,7 +278,7 @@ cpdef getattr_from_other_class(self, cls, name): sage: getattr_from_other_class(1, A, "lazy_attribute") Traceback (most recent call last): ... - AttributeError: 'sage.rings.integer.Integer' object has no attribute 'lazy_attribute' + AttributeError: 'sage.rings.integer.Integer' object has no attribute 'lazy_attribute'... The integer ring is a parent, so, lazy attributes work:: @@ -289,7 +289,7 @@ cpdef getattr_from_other_class(self, cls, name): sage: getattr_from_other_class(17, A, "lazy_attribute") Traceback (most recent call last): ... - AttributeError: 'sage.rings.integer.Integer' object has no attribute 'lazy_attribute' + AttributeError: 'sage.rings.integer.Integer' object has no attribute 'lazy_attribute'... In general, descriptors are not yet well supported, because they often do not accept to be cheated with the type of their instance:: @@ -305,7 +305,7 @@ cpdef getattr_from_other_class(self, cls, name): sage: getattr_from_other_class(1, A, "__weakref__") Traceback (most recent call last): ... - AttributeError: 'sage.rings.integer.Integer' object has no attribute '__weakref__' + AttributeError: 'sage.rings.integer.Integer' object has no attribute '__weakref__'... This was caught by :trac:`8296` for which we do a couple more tests:: @@ -314,7 +314,7 @@ cpdef getattr_from_other_class(self, cls, name): sage: 1.__weakref__ Traceback (most recent call last): ... - AttributeError: 'sage.rings.integer.Integer' object has no attribute '__weakref__' + AttributeError: 'sage.rings.integer.Integer' object has no attribute '__weakref__'... sage: n = 1 sage: ip = get_ipython() # not tested: only works in interactive shell @@ -329,7 +329,7 @@ cpdef getattr_from_other_class(self, cls, name): sage: getattr_from_other_class(1, A, "__call__") Traceback (most recent call last): ... - AttributeError: 'sage.rings.integer.Integer' object has no attribute '__call__' + AttributeError: 'sage.rings.integer.Integer' object has no attribute '__call__'... TESTS: @@ -339,14 +339,14 @@ cpdef getattr_from_other_class(self, cls, name): sage: getattr_from_other_class(1, type, "__name__") Traceback (most recent call last): ... - AttributeError: 'sage.rings.integer.Integer' object has no attribute '__name__' + AttributeError: 'sage.rings.integer.Integer' object has no attribute '__name__'... Non-strings as "name" are handled gracefully:: sage: getattr_from_other_class(1, type, None) Traceback (most recent call last): ... - AttributeError: 'sage.rings.integer.Integer' object has no attribute None + AttributeError: 'sage.rings.integer.Integer' object has no attribute None... """ if not isinstance(cls, type): raise TypeError(f"{cls!r} is not a type") diff --git a/src/sage/crypto/classical.py b/src/sage/crypto/classical.py index e5da119086a..e88ad4924bb 100644 --- a/src/sage/crypto/classical.py +++ b/src/sage/crypto/classical.py @@ -494,7 +494,7 @@ def rank_by_chi_square(self, C, pdict): sage: A.rank_by_chi_square("", Plist) Traceback (most recent call last): ... - AttributeError: 'str' object has no attribute 'parent' + AttributeError: 'str' object has no attribute 'parent'... sage: A.rank_by_chi_square(A.encoding(""), Plist) Traceback (most recent call last): ... @@ -703,7 +703,7 @@ def rank_by_squared_differences(self, C, pdict): sage: A.rank_by_squared_differences("", Plist) Traceback (most recent call last): ... - AttributeError: 'str' object has no attribute 'parent' + AttributeError: 'str' object has no attribute 'parent'... sage: A.rank_by_squared_differences(A.encoding(""), Plist) Traceback (most recent call last): ... @@ -2114,7 +2114,7 @@ def rank_by_chi_square(self, C, pdict): sage: S.rank_by_chi_square("", Pdict) Traceback (most recent call last): ... - AttributeError: 'str' object has no attribute 'parent' + AttributeError: 'str' object has no attribute 'parent'... sage: S.rank_by_chi_square(S.encoding(""), Pdict) Traceback (most recent call last): ... @@ -2351,7 +2351,7 @@ def rank_by_squared_differences(self, C, pdict): sage: S.rank_by_squared_differences("", Pdict) Traceback (most recent call last): ... - AttributeError: 'str' object has no attribute 'parent' + AttributeError: 'str' object has no attribute 'parent'... sage: S.rank_by_squared_differences(S.encoding(""), Pdict) Traceback (most recent call last): ... diff --git a/src/sage/crypto/mq/mpolynomialsystemgenerator.py b/src/sage/crypto/mq/mpolynomialsystemgenerator.py index 9028dab1d98..4416d9ef7f6 100644 --- a/src/sage/crypto/mq/mpolynomialsystemgenerator.py +++ b/src/sage/crypto/mq/mpolynomialsystemgenerator.py @@ -156,7 +156,7 @@ def sbox(self): sage: msg.sbox() Traceback (most recent call last): ... - AttributeError: '' object has no attribute '_sbox' + AttributeError: '' object has no attribute '_sbox'... """ return self._sbox diff --git a/src/sage/data_structures/bitset.pyx b/src/sage/data_structures/bitset.pyx index 446062554c1..d9906b5edd2 100644 --- a/src/sage/data_structures/bitset.pyx +++ b/src/sage/data_structures/bitset.pyx @@ -967,7 +967,7 @@ cdef class FrozenBitset: sage: None | FrozenBitset('10101') Traceback (most recent call last): ... - AttributeError: 'NoneType' object has no attribute '_union' + AttributeError: 'NoneType' object has no attribute '_union'... """ return self._union(other) @@ -1037,7 +1037,7 @@ cdef class FrozenBitset: sage: None & FrozenBitset("101011") Traceback (most recent call last): ... - AttributeError: 'NoneType' object has no attribute 'intersection' + AttributeError: 'NoneType' object has no attribute 'intersection'... """ return self.intersection(other) @@ -1106,7 +1106,7 @@ cdef class FrozenBitset: sage: None - FrozenBitset('10101') Traceback (most recent call last): ... - AttributeError: 'NoneType' object has no attribute 'difference' + AttributeError: 'NoneType' object has no attribute 'difference'... """ return self.difference(other) @@ -1179,7 +1179,7 @@ cdef class FrozenBitset: sage: None ^^ FrozenBitset('11111' * 10) Traceback (most recent call last): ... - AttributeError: 'NoneType' object has no attribute 'symmetric_difference' + AttributeError: 'NoneType' object has no attribute 'symmetric_difference'... """ return self.symmetric_difference(other) diff --git a/src/sage/doctest/reporting.py b/src/sage/doctest/reporting.py index 361fea344c2..a3947c07e01 100644 --- a/src/sage/doctest/reporting.py +++ b/src/sage/doctest/reporting.py @@ -368,7 +368,7 @@ def report(self, source, timeout, return_code, results, output, pid=None): sage: DTR.report(None, None, None, None, None) Traceback (most recent call last): ... - AttributeError: 'NoneType' object has no attribute 'basename' + AttributeError: 'NoneType' object has no attribute 'basename'... The only-errors mode does not output anything on success:: diff --git a/src/sage/dynamics/finite_dynamical_system.py b/src/sage/dynamics/finite_dynamical_system.py index e5fbf568b7e..4295070615a 100644 --- a/src/sage/dynamics/finite_dynamical_system.py +++ b/src/sage/dynamics/finite_dynamical_system.py @@ -240,7 +240,7 @@ class DiscreteDynamicalSystem(SageObject, metaclass=ClasscallMetaclass): sage: D.inverse_evolution()(4) Traceback (most recent call last): ... - AttributeError: 'DiscreteDynamicalSystem' object has no attribute 'inverse_evolution' + AttributeError: 'DiscreteDynamicalSystem' object has no attribute 'inverse_evolution'... sage: D.orbit(3) [3, 5, 1] @@ -252,7 +252,7 @@ class DiscreteDynamicalSystem(SageObject, metaclass=ClasscallMetaclass): sage: D.inverse_evolution()(4) Traceback (most recent call last): ... - AttributeError: 'DiscreteDynamicalSystem' object has no attribute 'inverse_evolution' + AttributeError: 'DiscreteDynamicalSystem' object has no attribute 'inverse_evolution'... sage: D.orbit(3) [3, 5, 1] diff --git a/src/sage/geometry/cone.py b/src/sage/geometry/cone.py index 1b4a60b0013..c2a9252bd72 100644 --- a/src/sage/geometry/cone.py +++ b/src/sage/geometry/cone.py @@ -340,7 +340,7 @@ def Cone(rays, lattice=None, check=True, normalize=True): sage: Cone([(1,0), (0,1)], check=False, normalize=False) Traceback (most recent call last): ... - AttributeError: 'tuple' object has no attribute 'parent' + AttributeError: 'tuple' object has no attribute 'parent'... You can construct different "not" cones: not full-dimensional, not strictly convex, not containing any rays:: diff --git a/src/sage/geometry/fan.py b/src/sage/geometry/fan.py index 258544012fe..3aecc84a55b 100644 --- a/src/sage/geometry/fan.py +++ b/src/sage/geometry/fan.py @@ -443,7 +443,7 @@ def Fan(cones, rays=None, lattice=None, check=True, normalize=True, sage: P2c = Fan(cones, rays, check=False, normalize=False) Traceback (most recent call last): ... - AttributeError: 'tuple' object has no attribute 'parent' + AttributeError: 'tuple' object has no attribute 'parent'... Yet another way is to use functions :func:`FaceFan` and :func:`NormalFan` to construct fans from :class:`lattice polytopes diff --git a/src/sage/geometry/polyhedron/combinatorial_polyhedron/face_iterator.pyx b/src/sage/geometry/polyhedron/combinatorial_polyhedron/face_iterator.pyx index f0ac1e774a7..98782303012 100644 --- a/src/sage/geometry/polyhedron/combinatorial_polyhedron/face_iterator.pyx +++ b/src/sage/geometry/polyhedron/combinatorial_polyhedron/face_iterator.pyx @@ -351,7 +351,7 @@ cdef class FaceIterator_base(SageObject): sage: FaceIterator_base(2) # indirect doctest Traceback (most recent call last): ... - AttributeError: 'sage.rings.integer.Integer' object has no attribute 'combinatorial_polyhedron' + AttributeError: 'sage.rings.integer.Integer' object has no attribute 'combinatorial_polyhedron'... """ cdef int i sig_free(self.structure.atom_rep) diff --git a/src/sage/geometry/toric_plotter.py b/src/sage/geometry/toric_plotter.py index 50b4008eb0f..950e3ba7ff8 100644 --- a/src/sage/geometry/toric_plotter.py +++ b/src/sage/geometry/toric_plotter.py @@ -706,7 +706,7 @@ def set_rays(self, generators): sage: tp.plot_rays() # needs sage.plot Traceback (most recent call last): ... - AttributeError: 'ToricPlotter' object has no attribute 'rays' + AttributeError: 'ToricPlotter' object has no attribute 'rays'... sage: tp.set_rays([(0,1)]) sage: tp.plot_rays() # needs sage.plot Graphics object consisting of 2 graphics primitives diff --git a/src/sage/groups/matrix_gps/finitely_generated.py b/src/sage/groups/matrix_gps/finitely_generated.py index d0ec214bb3b..c8098ad578a 100644 --- a/src/sage/groups/matrix_gps/finitely_generated.py +++ b/src/sage/groups/matrix_gps/finitely_generated.py @@ -268,7 +268,7 @@ def MatrixGroup(*gens, **kwds): sage: SL2C.gens() Traceback (most recent call last): ... - AttributeError: 'LinearMatrixGroup_generic_with_category' object has no attribute 'gens' + AttributeError: 'LinearMatrixGroup_generic_with_category' object has no attribute 'gens'... """ if isinstance(gens[-1], dict): # hack for unpickling kwds.update(gens[-1]) diff --git a/src/sage/homology/chains.py b/src/sage/homology/chains.py index 87c0947c0b0..b9a54940943 100644 --- a/src/sage/homology/chains.py +++ b/src/sage/homology/chains.py @@ -298,7 +298,7 @@ def is_cycle(self): sage: chain.is_cocycle() Traceback (most recent call last): ... - AttributeError: 'Chains_with_category.element_class' object has no attribute 'is_cocycle' + AttributeError: 'Chains_with_category.element_class' object has no attribute 'is_cocycle'... """ return self.to_complex().is_cycle() @@ -325,7 +325,7 @@ def is_boundary(self): sage: chain.is_coboundary() Traceback (most recent call last): ... - AttributeError: 'Chains_with_category.element_class' object has no attribute 'is_coboundary' + AttributeError: 'Chains_with_category.element_class' object has no attribute 'is_coboundary'... """ return self.to_complex().is_boundary() @@ -539,7 +539,7 @@ def is_cocycle(self): sage: cochain.is_cycle() Traceback (most recent call last): ... - AttributeError: 'Cochains_with_category.element_class' object has no attribute 'is_cycle' + AttributeError: 'Cochains_with_category.element_class' object has no attribute 'is_cycle'... """ return self.to_complex().is_cycle() @@ -566,7 +566,7 @@ def is_coboundary(self): sage: cochain.is_boundary() Traceback (most recent call last): ... - AttributeError: 'Cochains_with_category.element_class' object has no attribute 'is_boundary' + AttributeError: 'Cochains_with_category.element_class' object has no attribute 'is_boundary'... """ return self.to_complex().is_boundary() @@ -604,7 +604,7 @@ def eval(self, other): sage: z.eval(c) # z is not a cochain Traceback (most recent call last): ... - AttributeError: 'Chains_with_category.element_class' object has no attribute 'eval' + AttributeError: 'Chains_with_category.element_class' object has no attribute 'eval'... sage: c.eval(c) # can't evaluate a cochain on a cochain Traceback (most recent call last): ... diff --git a/src/sage/homology/free_resolution.py b/src/sage/homology/free_resolution.py index e3d38de4240..280a479b438 100644 --- a/src/sage/homology/free_resolution.py +++ b/src/sage/homology/free_resolution.py @@ -275,7 +275,7 @@ def differential(self, i): sage: FreeResolution.differiental(r, 1) Traceback (most recent call last): ... - AttributeError: type object 'FreeResolution' has no attribute 'differiental' + AttributeError: type object 'FreeResolution' has no attribute 'differiental'... """ def target(self): diff --git a/src/sage/interfaces/magma.py b/src/sage/interfaces/magma.py index b7a0ac20d03..529bfbc349b 100644 --- a/src/sage/interfaces/magma.py +++ b/src/sage/interfaces/magma.py @@ -824,7 +824,7 @@ def _coerce_from_special_method(self, x): sage: magma._coerce_from_special_method('2 + 3') # optional - magma Traceback (most recent call last): ... - AttributeError: 'str' object has no attribute '_magma_init_' + AttributeError: 'str' object has no attribute '_magma_init_'... """ s = x._magma_init_(self) a = self(s) diff --git a/src/sage/libs/gap/element.pyx b/src/sage/libs/gap/element.pyx index 478caf9f9d0..363024ae281 100644 --- a/src/sage/libs/gap/element.pyx +++ b/src/sage/libs/gap/element.pyx @@ -380,7 +380,7 @@ cdef GapElement make_GapElement(parent, Obj obj): sage: libgap(None) Traceback (most recent call last): ... - AttributeError: 'NoneType' object has no attribute '_libgap_init_' + AttributeError: 'NoneType' object has no attribute '_libgap_init_'... """ cdef GapElement r = GapElement.__new__(GapElement) r._initialize(parent, obj) diff --git a/src/sage/manifolds/calculus_method.py b/src/sage/manifolds/calculus_method.py index f5830c0bc45..303dde6cd13 100644 --- a/src/sage/manifolds/calculus_method.py +++ b/src/sage/manifolds/calculus_method.py @@ -257,7 +257,7 @@ def simplify(self, expression, method=None): sage: cm.simplify(f) Traceback (most recent call last): ... - AttributeError: 'sage.symbolic.expression.Expression' object has no attribute 'combsimp' + AttributeError: 'sage.symbolic.expression.Expression' object has no attribute 'combsimp'... In the present case, one should either transform ``f`` to a SymPy object:: diff --git a/src/sage/manifolds/differentiable/vectorfield_module.py b/src/sage/manifolds/differentiable/vectorfield_module.py index 11b94366a40..ea7307f810d 100644 --- a/src/sage/manifolds/differentiable/vectorfield_module.py +++ b/src/sage/manifolds/differentiable/vectorfield_module.py @@ -885,7 +885,7 @@ def tensor(self, *args, **kwds): sage: XM.tensor(XM).tensor(XM.dual().tensor(XM.dual())) Traceback (most recent call last): ... - AttributeError: 'TensorFieldModule_with_category' object has no attribute '_basis_sym' + AttributeError: 'TensorFieldModule_with_category' object has no attribute '_basis_sym'... .. SEEALSO:: diff --git a/src/sage/matrix/matrix2.pyx b/src/sage/matrix/matrix2.pyx index 86aca6e00d8..a5f6716e731 100644 --- a/src/sage/matrix/matrix2.pyx +++ b/src/sage/matrix/matrix2.pyx @@ -15303,7 +15303,7 @@ cdef class Matrix(Matrix1): Traceback (most recent call last): ... AttributeError: 'sage.rings.finite_rings.integer_mod.IntegerMod_int' object - has no attribute 'conjugate' + has no attribute 'conjugate'... """ # limited testing on a 1000 x 1000 matrix over CC: # transpose is fast, conjugate is slow diff --git a/src/sage/matrix/matrix_cyclo_dense.pyx b/src/sage/matrix/matrix_cyclo_dense.pyx index f54f3423ded..a49bb6240e6 100644 --- a/src/sage/matrix/matrix_cyclo_dense.pyx +++ b/src/sage/matrix/matrix_cyclo_dense.pyx @@ -847,7 +847,7 @@ cdef class Matrix_cyclo_dense(Matrix_dense): sage: A.set_mutable() Traceback (most recent call last): ... - AttributeError: 'sage.matrix.matrix_cyclo_dense.Matrix_cyclo_dense' object has no attribute 'set_mutable' + AttributeError: 'sage.matrix.matrix_cyclo_dense.Matrix_cyclo_dense' object has no attribute 'set_mutable'... sage: B = A.__copy__() sage: B[0,0] = 20 sage: B[0,0] diff --git a/src/sage/matrix/matrix_gfpn_dense.pyx b/src/sage/matrix/matrix_gfpn_dense.pyx index 4cccf473de1..8e8e4d7336b 100644 --- a/src/sage/matrix/matrix_gfpn_dense.pyx +++ b/src/sage/matrix/matrix_gfpn_dense.pyx @@ -159,7 +159,7 @@ cdef class FieldConverter_class: sage: C.field_to_fel('foo') Traceback (most recent call last): ... - AttributeError: 'str' object has no attribute 'to_integer' + AttributeError: 'str' object has no attribute 'to_integer'... """ return FfFromInt(x.to_integer()) diff --git a/src/sage/matrix/matrix_space.py b/src/sage/matrix/matrix_space.py index 6aab58352be..b5e6f52349b 100644 --- a/src/sage/matrix/matrix_space.py +++ b/src/sage/matrix/matrix_space.py @@ -1619,7 +1619,7 @@ def __getitem__(self, x): sage: MS[2] Traceback (most recent call last): ... - AttributeError: 'MatrixSpace_with_category' object has no attribute 'list' + AttributeError: 'MatrixSpace_with_category' object has no attribute 'list'... """ if isinstance(x, (integer.Integer, int)): return self.list()[x] diff --git a/src/sage/matroids/linear_matroid.pyx b/src/sage/matroids/linear_matroid.pyx index 36f563aa433..318c82f2b64 100644 --- a/src/sage/matroids/linear_matroid.pyx +++ b/src/sage/matroids/linear_matroid.pyx @@ -1134,7 +1134,7 @@ cdef class LinearMatroid(BasisExchangeMatroid): Traceback (most recent call last): ... AttributeError: 'sage.matroids.basis_matroid.BasisMatroid' object - has no attribute 'base_ring' + has no attribute 'base_ring'... sage: from sage.matroids.advanced import * sage: M4 = BinaryMatroid(Matrix(M1)) sage: M5 = LinearMatroid(reduced_matrix=Matrix(GF(2), [[-1, 0, 1], diff --git a/src/sage/misc/functional.py b/src/sage/misc/functional.py index c922b8f6f12..03697f08b7c 100644 --- a/src/sage/misc/functional.py +++ b/src/sage/misc/functional.py @@ -86,7 +86,7 @@ def base_field(x): sage: R.base_field() Traceback (most recent call last): ... - AttributeError: 'PolynomialRing_dense_mod_p_with_category' object has no attribute 'base_field' + AttributeError: 'PolynomialRing_dense_mod_p_with_category' object has no attribute 'base_field'... """ try: return x.base_field() diff --git a/src/sage/misc/instancedoc.pyx b/src/sage/misc/instancedoc.pyx index d8e1e4ac536..44ee70f64ba 100644 --- a/src/sage/misc/instancedoc.pyx +++ b/src/sage/misc/instancedoc.pyx @@ -256,7 +256,7 @@ cdef class InstanceDocDescriptor: sage: descr.__delete__(obj) Traceback (most recent call last): ... - AttributeError: 'X' object has no attribute '__doc__' + AttributeError: 'X' object has no attribute '__doc__'... sage: descr.__delete__([]) Traceback (most recent call last): diff --git a/src/sage/misc/lazy_attribute.pyx b/src/sage/misc/lazy_attribute.pyx index bdbec3b3ba1..1f07870b8ec 100644 --- a/src/sage/misc/lazy_attribute.pyx +++ b/src/sage/misc/lazy_attribute.pyx @@ -441,37 +441,37 @@ class lazy_attribute(_lazy_attribute): sage: B().unimplemented_A # todo: not implemented Traceback (most recent call last): ... - AttributeError: 'super' object has no attribute 'unimplemented_A' + AttributeError: 'super' object has no attribute 'unimplemented_A'... We now make some systematic checks:: sage: B().unimplemented_A Traceback (most recent call last): ... - AttributeError: '...' object has no attribute 'unimplemented_A' + AttributeError: '...' object has no attribute 'unimplemented_A'... sage: B().unimplemented_B Traceback (most recent call last): ... - AttributeError: '...' object has no attribute 'unimplemented_B' + AttributeError: '...' object has no attribute 'unimplemented_B'... sage: B().unimplemented_AB Traceback (most recent call last): ... - AttributeError: '...' object has no attribute 'unimplemented_AB' + AttributeError: '...' object has no attribute 'unimplemented_AB'... sage: B().unimplemented_B_implemented_A 1 sage: C().unimplemented_A() Traceback (most recent call last): ... - AttributeError: '...' object has no attribute 'unimplemented_A' + AttributeError: '...' object has no attribute 'unimplemented_A'... sage: C().unimplemented_B() Traceback (most recent call last): ... - AttributeError: '...' object has no attribute 'unimplemented_B' + AttributeError: '...' object has no attribute 'unimplemented_B'... sage: C().unimplemented_AB() Traceback (most recent call last): ... - AttributeError: '...' object has no attribute 'unimplemented_AB' + AttributeError: '...' object has no attribute 'unimplemented_AB'... sage: C().unimplemented_B_implemented_A # todo: not implemented 1 """ diff --git a/src/sage/misc/object_multiplexer.py b/src/sage/misc/object_multiplexer.py index d4e811ef16e..00fd89d6652 100644 --- a/src/sage/misc/object_multiplexer.py +++ b/src/sage/misc/object_multiplexer.py @@ -85,7 +85,7 @@ def __getattr__(self, name): sage: m.__bork__ Traceback (most recent call last): ... - AttributeError: 'Multiplex' has no attribute '__bork__' + AttributeError: 'Multiplex' has no attribute '__bork__'... """ if name.startswith("__"): raise AttributeError("'Multiplex' has no attribute '%s'" % name) diff --git a/src/sage/misc/sage_input.py b/src/sage/misc/sage_input.py index 66e78ecccbc..00e8d96ee9e 100644 --- a/src/sage/misc/sage_input.py +++ b/src/sage/misc/sage_input.py @@ -3461,7 +3461,7 @@ def verify_same(a, b): sage: verify_same(1, 1r) Traceback (most recent call last): ... - AttributeError: 'int' object has no attribute 'parent' + AttributeError: 'int' object has no attribute 'parent'... sage: verify_same(1r, 1) Traceback (most recent call last): ... @@ -3525,7 +3525,7 @@ def verify_si_answer(x, answer, preparse): sage: verify_si_answer(1, '1', False) Traceback (most recent call last): ... - AttributeError: 'int' object has no attribute 'parent' + AttributeError: 'int' object has no attribute 'parent'... sage: verify_si_answer(1, 'ZZ(1)', None) """ from sage.misc.sage_eval import sage_eval diff --git a/src/sage/modules/fp_graded/steenrod/module.py b/src/sage/modules/fp_graded/steenrod/module.py index 18460b0e9a1..4acfa6b4002 100755 --- a/src/sage/modules/fp_graded/steenrod/module.py +++ b/src/sage/modules/fp_graded/steenrod/module.py @@ -70,7 +70,7 @@ sage: SteenrodFPModule(ZZ, [0]) Traceback (most recent call last): ... - AttributeError: 'sage.rings.integer_ring.IntegerRing_class' object has no attribute 'free_graded_module' + AttributeError: 'sage.rings.integer_ring.IntegerRing_class' object has no attribute 'free_graded_module'... AUTHORS: diff --git a/src/sage/parallel/map_reduce.py b/src/sage/parallel/map_reduce.py index 11e0673ee91..5441943731d 100644 --- a/src/sage/parallel/map_reduce.py +++ b/src/sage/parallel/map_reduce.py @@ -1234,7 +1234,7 @@ def finish(self): sage: S.print_communication_statistics() Traceback (most recent call last): ... - AttributeError: 'RESetMPExample' object has no attribute '_stats' + AttributeError: 'RESetMPExample' object has no attribute '_stats'... sage: S.finish() diff --git a/src/sage/plot/colors.py b/src/sage/plot/colors.py index 8c0db2b3c34..3281199400b 100644 --- a/src/sage/plot/colors.py +++ b/src/sage/plot/colors.py @@ -1099,7 +1099,7 @@ def __getattr__(self, name): sage: cols.punk Traceback (most recent call last): ... - AttributeError: 'ColorsDict' has no attribute or colormap punk + AttributeError: 'ColorsDict' has no attribute or colormap punk... """ try: return self[name] @@ -1599,7 +1599,7 @@ def __getattr__(self, name): sage: maps.punk Traceback (most recent call last): ... - AttributeError: 'Colormaps' has no attribute or colormap punk + AttributeError: 'Colormaps' has no attribute or colormap punk... sage: maps['punk'] Traceback (most recent call last): ... diff --git a/src/sage/rings/asymptotic/asymptotic_ring.py b/src/sage/rings/asymptotic/asymptotic_ring.py index b07319382d3..994490e6616 100644 --- a/src/sage/rings/asymptotic/asymptotic_ring.py +++ b/src/sage/rings/asymptotic/asymptotic_ring.py @@ -1091,7 +1091,7 @@ def monomial_coefficient(self, monomial): sage: O(n).monomial_coefficient(n) Traceback (most recent call last): ... - AttributeError: 'OTermMonoid_with_category.element_class' object has no attribute 'coefficient' + AttributeError: 'OTermMonoid_with_category.element_class' object has no attribute 'coefficient'... The ``monomial`` must be exact:: diff --git a/src/sage/rings/asymptotic/growth_group.py b/src/sage/rings/asymptotic/growth_group.py index 906a0dbae57..3744eb2027f 100644 --- a/src/sage/rings/asymptotic/growth_group.py +++ b/src/sage/rings/asymptotic/growth_group.py @@ -1572,7 +1572,7 @@ def variable_names(self): Traceback (most recent call last): ... AttributeError: 'GenericGrowthGroup_with_category.element_class' object - has no attribute 'is_one' + has no attribute 'is_one'... """ if self.is_one(): return tuple() diff --git a/src/sage/rings/ideal.py b/src/sage/rings/ideal.py index d36d9406f32..01c9fa3bf2d 100644 --- a/src/sage/rings/ideal.py +++ b/src/sage/rings/ideal.py @@ -1553,7 +1553,7 @@ def gcd(self, other): sage: J.gcd(I) Traceback (most recent call last): ... - AttributeError: 'Ideal_generic' object has no attribute 'gcd' + AttributeError: 'Ideal_generic' object has no attribute 'gcd'... Note:: diff --git a/src/sage/rings/number_field/number_field.py b/src/sage/rings/number_field/number_field.py index b4ba6de1362..7ffeeca710b 100644 --- a/src/sage/rings/number_field/number_field.py +++ b/src/sage/rings/number_field/number_field.py @@ -3823,7 +3823,7 @@ def primes_above(self, x, degree=None): sage: F.prime_above(0) Traceback (most recent call last): ... - AttributeError: 'NumberFieldIdeal' object has no attribute 'prime_factors' + AttributeError: 'NumberFieldIdeal' object has no attribute 'prime_factors'... """ if degree is not None: degree = ZZ(degree) @@ -3917,7 +3917,7 @@ def prime_above(self, x, degree=None): sage: F.prime_above(0) Traceback (most recent call last): ... - AttributeError: 'NumberFieldIdeal' object has no attribute 'prime_factors' + AttributeError: 'NumberFieldIdeal' object has no attribute 'prime_factors'... """ ids = self.primes_above(x, degree) @@ -5926,7 +5926,7 @@ def factor(self, n): sage: L.factor(0) Traceback (most recent call last): ... - AttributeError: 'NumberFieldIdeal' object has no attribute 'factor' + AttributeError: 'NumberFieldIdeal' object has no attribute 'factor'... AUTHORS: @@ -12698,7 +12698,7 @@ def is_real_place(v): sage: is_real_place(v_fin) Traceback (most recent call last): ... - AttributeError: 'NumberFieldFractionalIdeal' object has no attribute 'im_gens' + AttributeError: 'NumberFieldFractionalIdeal' object has no attribute 'im_gens'... """ RR = sage.rings.real_mpfr.RealField(53) diff --git a/src/sage/rings/padics/generic_nodes.py b/src/sage/rings/padics/generic_nodes.py index 7047020edec..b6b514d4005 100644 --- a/src/sage/rings/padics/generic_nodes.py +++ b/src/sage/rings/padics/generic_nodes.py @@ -740,7 +740,7 @@ def _get_element_class(self, name=None): sage: R._get_element_class("foobar") Traceback (most recent call last): ... - AttributeError: module 'sage.rings.padics.padic_relaxed_element' has no attribute 'pAdicRelaxedElement_foobar' + AttributeError: module 'sage.rings.padics.padic_relaxed_element' has no attribute 'pAdicRelaxedElement_foobar'... """ if name is None: return self.Element diff --git a/src/sage/rings/polynomial/polynomial_element.pyx b/src/sage/rings/polynomial/polynomial_element.pyx index c5a1129aecf..a5b7f937cfe 100644 --- a/src/sage/rings/polynomial/polynomial_element.pyx +++ b/src/sage/rings/polynomial/polynomial_element.pyx @@ -10793,7 +10793,7 @@ cdef class Polynomial(CommutativePolynomial): sage: (y**2 + x).nth_root(2) Traceback (most recent call last): ... - AttributeError: ... has no attribute 'nth_root' + AttributeError: ... has no attribute 'nth_root'... TESTS:: @@ -11831,7 +11831,7 @@ cdef class Polynomial_generic_dense(Polynomial): sage: int(1) // x # check that this doesn't segfault Traceback (most recent call last): ... - AttributeError: type object 'int' has no attribute 'base_ring' + AttributeError: type object 'int' has no attribute 'base_ring'... """ if have_same_parent(self, right): return (self)._floordiv_(right) diff --git a/src/sage/rings/polynomial/polynomial_quotient_ring.py b/src/sage/rings/polynomial/polynomial_quotient_ring.py index 99d90a5c8f7..ee97f641990 100644 --- a/src/sage/rings/polynomial/polynomial_quotient_ring.py +++ b/src/sage/rings/polynomial/polynomial_quotient_ring.py @@ -2362,7 +2362,7 @@ def field_extension(self, names): sage: F, g, h = S.field_extension('b') # needs sage.rings.finite_rings Traceback (most recent call last): ... - AttributeError: 'PolynomialQuotientRing_generic_with_category' object has no attribute 'field_extension' + AttributeError: 'PolynomialQuotientRing_generic_with_category' object has no attribute 'field_extension'... Over a finite field, the corresponding field extension is not a number field:: diff --git a/src/sage/rings/ring.pyx b/src/sage/rings/ring.pyx index 5273891a5b0..a6e999b8805 100644 --- a/src/sage/rings/ring.pyx +++ b/src/sage/rings/ring.pyx @@ -1734,7 +1734,7 @@ cdef class IntegralDomain(CommutativeRing): sage: Z5.is_integrally_closed() Traceback (most recent call last): ... - AttributeError: 'IntegerModRing_generic_with_category' object has no attribute 'is_integrally_closed' + AttributeError: 'IntegerModRing_generic_with_category' object has no attribute 'is_integrally_closed'... """ raise NotImplementedError diff --git a/src/sage/schemes/toric/morphism.py b/src/sage/schemes/toric/morphism.py index 1c8944b6dfc..5d64d632f97 100644 --- a/src/sage/schemes/toric/morphism.py +++ b/src/sage/schemes/toric/morphism.py @@ -246,7 +246,7 @@ Traceback (most recent call last): ... AttributeError: 'SchemeMorphism_fan_toric_variety' object - has no attribute 'fiber_generic' + has no attribute 'fiber_generic'... Let's use factorization mentioned above:: diff --git a/src/sage/sets/disjoint_union_enumerated_sets.py b/src/sage/sets/disjoint_union_enumerated_sets.py index 2375f4d191a..d6e7fbdde72 100644 --- a/src/sage/sets/disjoint_union_enumerated_sets.py +++ b/src/sage/sets/disjoint_union_enumerated_sets.py @@ -619,7 +619,7 @@ def Element(self): Traceback (most recent call last): ... AttributeError: 'DisjointUnionEnumeratedSets_with_category' object - has no attribute 'Element' + has no attribute 'Element'... """ if not self._facade: return ElementWrapper diff --git a/src/sage/sets/set.py b/src/sage/sets/set.py index 4e8789a2d57..a6a746e9aca 100644 --- a/src/sage/sets/set.py +++ b/src/sage/sets/set.py @@ -167,7 +167,7 @@ def Set(X=None, category=None): sage: sorted(B.list(), key=repr) Traceback (most recent call last): ... - AttributeError: 'Set_object_with_category' object has no attribute 'list' + AttributeError: 'Set_object_with_category' object has no attribute 'list'... sage: type(B) diff --git a/src/sage/structure/category_object.pyx b/src/sage/structure/category_object.pyx index b6a7eaecb5b..c06933494dc 100644 --- a/src/sage/structure/category_object.pyx +++ b/src/sage/structure/category_object.pyx @@ -836,7 +836,7 @@ cdef class CategoryObject(SageObject): sage: Sets().example().sadfasdf Traceback (most recent call last): ... - AttributeError: 'PrimeNumbers_with_category' object has no attribute 'sadfasdf' + AttributeError: 'PrimeNumbers_with_category' object has no attribute 'sadfasdf'... """ return self.getattr_from_category(name) diff --git a/src/sage/structure/element.pyx b/src/sage/structure/element.pyx index caae7e40ffc..41b022a3fd7 100644 --- a/src/sage/structure/element.pyx +++ b/src/sage/structure/element.pyx @@ -219,7 +219,7 @@ the parents:: sage: x._add_(x) Traceback (most recent call last): ... - AttributeError: 'sage.structure.element.Element' object has no attribute '_add_' + AttributeError: 'sage.structure.element.Element' object has no attribute '_add_'... sage: x + x Traceback (most recent call last): ... @@ -478,13 +478,13 @@ cdef class Element(SageObject): sage: 1.blah_blah Traceback (most recent call last): ... - AttributeError: 'sage.rings.integer.Integer' object has no attribute 'blah_blah' + AttributeError: 'sage.rings.integer.Integer' object has no attribute 'blah_blah'... sage: Semigroups().example().an_element().is_idempotent sage: Semigroups().example().an_element().blah_blah Traceback (most recent call last): ... - AttributeError: 'LeftZeroSemigroup_with_category.element_class' object has no attribute 'blah_blah' + AttributeError: 'LeftZeroSemigroup_with_category.element_class' object has no attribute 'blah_blah'... """ return self.getattr_from_category(name) @@ -1269,7 +1269,7 @@ cdef class Element(SageObject): sage: e._add_(e) Traceback (most recent call last): ... - AttributeError: 'sage.structure.element.Element' object has no attribute '_add_' + AttributeError: 'sage.structure.element.Element' object has no attribute '_add_'... """ try: python_op = (self)._add_ @@ -1381,7 +1381,7 @@ cdef class Element(SageObject): sage: e._sub_(e) Traceback (most recent call last): ... - AttributeError: 'sage.structure.element.Element' object has no attribute '_sub_' + AttributeError: 'sage.structure.element.Element' object has no attribute '_sub_'... """ try: python_op = (self)._sub_ @@ -1435,7 +1435,7 @@ cdef class Element(SageObject): sage: e._neg_() Traceback (most recent call last): ... - AttributeError: 'sage.structure.element.Element' object has no attribute '_neg_' + AttributeError: 'sage.structure.element.Element' object has no attribute '_neg_'... """ try: python_op = (self)._neg_ @@ -1549,7 +1549,7 @@ cdef class Element(SageObject): sage: e._mul_(e) Traceback (most recent call last): ... - AttributeError: 'sage.structure.element.Element' object has no attribute '_mul_' + AttributeError: 'sage.structure.element.Element' object has no attribute '_mul_'... """ try: python_op = (self)._mul_ @@ -1662,7 +1662,7 @@ cdef class Element(SageObject): sage: e._matmul_(e) Traceback (most recent call last): ... - AttributeError: 'sage.structure.element.Element' object has no attribute '_matmul_' + AttributeError: 'sage.structure.element.Element' object has no attribute '_matmul_'... """ try: python_op = (self)._matmul_ @@ -1765,7 +1765,7 @@ cdef class Element(SageObject): sage: e._div_(e) Traceback (most recent call last): ... - AttributeError: 'sage.structure.element.Element' object has no attribute '_div_' + AttributeError: 'sage.structure.element.Element' object has no attribute '_div_'... """ try: python_op = (self)._div_ @@ -1865,7 +1865,7 @@ cdef class Element(SageObject): sage: e._floordiv_(e) Traceback (most recent call last): ... - AttributeError: 'sage.structure.element.Element' object has no attribute '_floordiv_' + AttributeError: 'sage.structure.element.Element' object has no attribute '_floordiv_'... """ try: python_op = (self)._floordiv_ @@ -1965,7 +1965,7 @@ cdef class Element(SageObject): sage: e._mod_(e) Traceback (most recent call last): ... - AttributeError: 'sage.structure.element.Element' object has no attribute '_mod_' + AttributeError: 'sage.structure.element.Element' object has no attribute '_mod_'... """ try: python_op = (self)._mod_ @@ -2092,7 +2092,7 @@ cdef class Element(SageObject): sage: e._pow_(e) Traceback (most recent call last): ... - AttributeError: 'sage.structure.element.Element' object has no attribute '_pow_' + AttributeError: 'sage.structure.element.Element' object has no attribute '_pow_'... """ try: python_op = (self)._pow_ @@ -2122,7 +2122,7 @@ cdef class Element(SageObject): sage: e._pow_int(e) Traceback (most recent call last): ... - AttributeError: 'sage.structure.element.Element' object has no attribute '_pow_int' + AttributeError: 'sage.structure.element.Element' object has no attribute '_pow_int'... """ try: python_op = (self)._pow_int @@ -2856,7 +2856,7 @@ cdef class RingElement(ModuleElement): sage: m.is_nilpotent() # needs sage.modules Traceback (most recent call last): ... - AttributeError: ... object has no attribute 'is_nilpotent' + AttributeError: ... object has no attribute 'is_nilpotent'... """ if self.is_unit(): return False @@ -4671,7 +4671,7 @@ def coerce_binop(method): sage: x.test_add(CC(2)) Traceback (most recent call last): ... - AttributeError: 'sage.rings.complex_mpfr.ComplexNumber' object has no attribute 'test_add' + AttributeError: 'sage.rings.complex_mpfr.ComplexNumber' object has no attribute 'test_add'... TESTS: diff --git a/src/sage/structure/sequence.py b/src/sage/structure/sequence.py index 0c700c1fb81..c3972532ac3 100644 --- a/src/sage/structure/sequence.py +++ b/src/sage/structure/sequence.py @@ -854,7 +854,7 @@ def __getattr__(self, name): sage: S.universe() Traceback (most recent call last): ... - AttributeError: 'Sequence_generic' object has no attribute '_Sequence_generic__universe' + AttributeError: 'Sequence_generic' object has no attribute '_Sequence_generic__universe'... sage: S._Sequence__universe = 'foobar' sage: S.universe() 'foobar' @@ -867,7 +867,7 @@ def __getattr__(self, name): sage: hash(S) Traceback (most recent call last): ... - AttributeError: 'Sequence_generic' object has no attribute '_Sequence_generic__hash' + AttributeError: 'Sequence_generic' object has no attribute '_Sequence_generic__hash'... sage: S._Sequence__hash = int(34) sage: hash(S) 34 diff --git a/src/sage/symbolic/pynac_impl.pxi b/src/sage/symbolic/pynac_impl.pxi index 68c31dcfde7..7fd7c3b314b 100644 --- a/src/sage/symbolic/pynac_impl.pxi +++ b/src/sage/symbolic/pynac_impl.pxi @@ -619,7 +619,7 @@ def tolerant_is_symbol(a): sage: None.is_symbol() Traceback (most recent call last): ... - AttributeError: 'NoneType' object has no attribute 'is_symbol' + AttributeError: 'NoneType' object has no attribute 'is_symbol'... """ try: return a.is_symbol() From 5e34da9bf9b310e1f10b007f3c26a6b90e34f609 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gonzalo=20Tornar=C3=ADa?= Date: Tue, 3 Oct 2023 20:20:41 -0300 Subject: [PATCH 074/216] py312: fix AttributeError doctests (manual changes) In python 3.12, attribute errors add a suggestion at the end of the usual error message ("Did you mean ...?"). We add ... at the end of these doctest outputs to fix it. This commit has a few manual changes which didn't match the sed pattern in the previous commit. --- src/sage/structure/element.pyx | 2 +- src/sage/symbolic/assumptions.py | 2 +- src/sage/symbolic/expression.pyx | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sage/structure/element.pyx b/src/sage/structure/element.pyx index 41b022a3fd7..543506e9a74 100644 --- a/src/sage/structure/element.pyx +++ b/src/sage/structure/element.pyx @@ -2856,7 +2856,7 @@ cdef class RingElement(ModuleElement): sage: m.is_nilpotent() # needs sage.modules Traceback (most recent call last): ... - AttributeError: ... object has no attribute 'is_nilpotent'... + AttributeError: '...' object has no attribute 'is_nilpotent'... """ if self.is_unit(): return False diff --git a/src/sage/symbolic/assumptions.py b/src/sage/symbolic/assumptions.py index 7dcb15f0d85..15f6fa07ce6 100644 --- a/src/sage/symbolic/assumptions.py +++ b/src/sage/symbolic/assumptions.py @@ -636,7 +636,7 @@ def assume(*args): Traceback (most recent call last): ... AttributeError: 'sage.rings.integer.Integer' object has no - attribute 'assume' + attribute 'assume'... Ensure that we can combine the two types of assumptions, as documented:: diff --git a/src/sage/symbolic/expression.pyx b/src/sage/symbolic/expression.pyx index 0f251ac4e5c..66f624141b3 100644 --- a/src/sage/symbolic/expression.pyx +++ b/src/sage/symbolic/expression.pyx @@ -13712,7 +13712,7 @@ cdef get_dynamic_class_for_function(unsigned serial): Traceback (most recent call last): ... AttributeError: 'sage.symbolic.expression.Expression' object has no - attribute 'argp1' + attribute 'argp1'... sage: t = (e + 1).op[0]; t tfunc(x) sage: t From 6566b91b707b6ed25e5ec21e6d6b9862e7213043 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 8 Oct 2023 17:20:12 -0700 Subject: [PATCH 075/216] build/pkgs/attrs: Change to wheel package, update dependencies --- build/pkgs/attrs/checksums.ini | 10 +++++----- build/pkgs/attrs/dependencies | 2 +- build/pkgs/attrs/spkg-install.in | 14 -------------- 3 files changed, 6 insertions(+), 20 deletions(-) delete mode 100644 build/pkgs/attrs/spkg-install.in diff --git a/build/pkgs/attrs/checksums.ini b/build/pkgs/attrs/checksums.ini index 2b364ba1a75..74904048262 100644 --- a/build/pkgs/attrs/checksums.ini +++ b/build/pkgs/attrs/checksums.ini @@ -1,5 +1,5 @@ -tarball=attrs-VERSION.tar.gz -sha1=f48d0c0f96e3fbd476821408b81f5c823026546e -md5=6623fed7ffa22261ba25fccaf4d99539 -cksum=3377712336 -upstream_url=https://pypi.io/packages/source/a/attrs/attrs-VERSION.tar.gz +tarball=attrs-VERSION-py3-none-any.whl +sha1=d916b1ecad441ce7f07d86034085475f6c231830 +md5=5aecf1f8857233a04c1926ea68e8f860 +cksum=1934687514 +upstream_url=https://pypi.io/packages/py3/a/attrs/attrs-VERSION-py3-none-any.whl diff --git a/build/pkgs/attrs/dependencies b/build/pkgs/attrs/dependencies index 9be6b4aab7c..47296a7bace 100644 --- a/build/pkgs/attrs/dependencies +++ b/build/pkgs/attrs/dependencies @@ -1,4 +1,4 @@ - vcversioner | $(PYTHON_TOOLCHAIN) $(PYTHON) + | $(PYTHON_TOOLCHAIN) $(PYTHON) ---------- All lines of this file are ignored except the first. diff --git a/build/pkgs/attrs/spkg-install.in b/build/pkgs/attrs/spkg-install.in deleted file mode 100644 index b71a7e4d7e9..00000000000 --- a/build/pkgs/attrs/spkg-install.in +++ /dev/null @@ -1,14 +0,0 @@ -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 attrs ... exiting" - exit 1 -fi From 0b7e125a2d3de6249cf0132f6642d9ca49394a86 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 8 Oct 2023 17:28:06 -0700 Subject: [PATCH 076/216] .github/workflows/ci-linux.yml: Run ubuntu-focal-standard without waiting for other platforms --- .github/workflows/ci-linux.yml | 39 ++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/.github/workflows/ci-linux.yml b/.github/workflows/ci-linux.yml index 665a2a4f0b0..8c422cb905e 100644 --- a/.github/workflows/ci-linux.yml +++ b/.github/workflows/ci-linux.yml @@ -34,7 +34,46 @@ permissions: jobs: + # The default platform used by build.yml etc. + + default-pre: + uses: ./.github/workflows/docker.yml + with: + # Build from scratch + docker_targets: "with-system-packages configured with-targets-pre" + # FIXME: duplicated from env.TARGETS + targets_pre: all-sage-local + tox_system_factors: >- + ["ubuntu-focal"] + tox_packages_factors: >- + ["standard"] + docker_push_repository: ghcr.io/${{ github.repository }}/ + + default: + if: ${{ success() || failure() }} + needs: [default-pre] + uses: ./.github/workflows/docker.yml + with: + # Build incrementally from previous stage (pre) + incremental: true + free_disk_space: true + from_docker_repository: ghcr.io/${{ github.repository }}/ + from_docker_target: "with-targets-pre" + docker_targets: "with-targets with-targets-optional" + # FIXME: duplicated from env.TARGETS + targets: build doc-html + targets_optional: ptest + tox_system_factors: >- + ["ubuntu-focal"] + tox_packages_factors: >- + ["standard"] + docker_push_repository: ghcr.io/${{ github.repository }}/ + + # All platforms. This duplicates the default platform, but why not, + # it makes it more robust regarding random timeouts. + standard-pre: + if: ${{ success() || failure() }} uses: ./.github/workflows/docker.yml with: # Build from scratch From b103592505285534d43b2248dc4abbd2d38f9daf Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 5 Oct 2023 12:44:04 -0700 Subject: [PATCH 077/216] README.md: Recommend configure --config-cache --- README.md | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 1b350a7996a..fa6bd2f2a11 100644 --- a/README.md +++ b/README.md @@ -319,12 +319,18 @@ in the Installation Guide. $ ./configure --help - A notable option for Sage developers is the following: - - - Use `./configure --enable-download-from-upstream-url` to allow - downloading packages from their upstream URL if they cannot (yet) be - found on the Sage mirrors. This is useful for trying out ticket branches - that make package upgrades. + Notable options for Sage developers are the following: + + - Use the option `--config-cache` to have ``configure`` + keep a disk cache of configuration values. This gives a nice speedup + when trying out ticket branches that make package upgrades, which + involves automatic re-runs of the configuration step. + + - Use the option `--enable-ccache` to have Sage install and use the + optional package ``ccache``, which is preconfigured to keep a + disk cache of object files created from source files. This can give + a great speedup when switching between different branches, at the + expense of disk space use. 10. Optional, but highly recommended: Set some environment variables to customize the build. From abe8f7a806ee13d47b01bfaccc222790db9da61c Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 6 Oct 2023 14:13:45 -0700 Subject: [PATCH 078/216] build/pkgs/*/spkg-configure.m4: Remove some duplicated messages --- build/pkgs/glpk/spkg-configure.m4 | 11 ++++------- build/pkgs/mpc/spkg-configure.m4 | 2 -- build/pkgs/mpfr/spkg-configure.m4 | 2 -- build/pkgs/pkgconf/spkg-configure.m4 | 3 +-- 4 files changed, 5 insertions(+), 13 deletions(-) diff --git a/build/pkgs/glpk/spkg-configure.m4 b/build/pkgs/glpk/spkg-configure.m4 index 6fb7d64aa44..344c71f5277 100644 --- a/build/pkgs/glpk/spkg-configure.m4 +++ b/build/pkgs/glpk/spkg-configure.m4 @@ -8,18 +8,15 @@ SAGE_SPKG_CONFIGURE([glpk], [ glpk_ver=`$GLPSOL --version | grep ^GLPSOL | $SED -e 's/GLPSOL.*ver, v//g' 2>> config.log` AX_COMPARE_VERSION([$glpk_ver], [ge], [$SAGE_GLPK_MINVER], [ AC_CHECK_HEADER([glpk.h], [], [sage_spkg_install_glpk=yes]) - AC_SEARCH_LIBS([glp_config], [glpk], - [AC_MSG_RESULT([yes. Use system's glpk])], [ - AC_MSG_RESULT([no. Install glpk]) - sage_spkg_install_glpk=yes])dnl end-AC_SEARCH_LIBS - ], [sage_spkg_install_glpk=yes])dnl end-AX_COMPARE_VERSION + AC_SEARCH_LIBS([glp_config], [glpk], [], [sage_spkg_install_glpk=yes])dnl end-AC_SEARCH_LIBS + ], [sage_spkg_install_glpk=yes])dnl end-AX_COMPARE_VERSION ])dnl end-AS_IF ]) m4_popdef([SAGE_GLPK_MINVER]) ], [], [], [ AS_IF([test x$sage_spkg_install_glpk = xyes], [ AC_SUBST(SAGE_GLPK_PREFIX, ['$SAGE_LOCAL']) - AC_MSG_RESULT([using Sage's glpk SPKG])], [ + ], [ AC_SUBST(SAGE_GLPK_PREFIX, ['']) - AC_MSG_RESULT([using glpk from the system])]) + ]) ]) diff --git a/build/pkgs/mpc/spkg-configure.m4 b/build/pkgs/mpc/spkg-configure.m4 index 1e8c475e1ff..046b0938aaa 100644 --- a/build/pkgs/mpc/spkg-configure.m4 +++ b/build/pkgs/mpc/spkg-configure.m4 @@ -7,9 +7,7 @@ SAGE_SPKG_CONFIGURE([mpc], [ ], [], [], [ if test x$sage_spkg_install_mpc = xyes; then AC_SUBST(SAGE_MPC_PREFIX, ['$SAGE_LOCAL']) - AC_MSG_RESULT([using Sage's mpc SPKG]) else AC_SUBST(SAGE_MPC_PREFIX, ['']) - AC_MSG_RESULT([using mpc library from the system]) fi ]) diff --git a/build/pkgs/mpfr/spkg-configure.m4 b/build/pkgs/mpfr/spkg-configure.m4 index 47056d06c09..c1e879f10ec 100644 --- a/build/pkgs/mpfr/spkg-configure.m4 +++ b/build/pkgs/mpfr/spkg-configure.m4 @@ -7,9 +7,7 @@ SAGE_SPKG_CONFIGURE([mpfr], [ ], [], [], [ if test x$sage_spkg_install_mpfr = xyes; then AC_SUBST(SAGE_MPFR_PREFIX, ['$SAGE_LOCAL']) - AC_MSG_RESULT([using Sage's mpfr SPKG]) else AC_SUBST(SAGE_MPFR_PREFIX, ['']) - AC_MSG_RESULT([using mpfr library from the system]) fi ]) diff --git a/build/pkgs/pkgconf/spkg-configure.m4 b/build/pkgs/pkgconf/spkg-configure.m4 index 87795bf8cde..9538e644bf4 100644 --- a/build/pkgs/pkgconf/spkg-configure.m4 +++ b/build/pkgs/pkgconf/spkg-configure.m4 @@ -4,9 +4,8 @@ SAGE_SPKG_CONFIGURE( AS_IF([test -z "$PKG_CONFIG"], [ sage_spkg_install_pkgconf=yes AC_SUBST(SAGE_PKG_CONFIG_PATH, ['']) - AC_MSG_RESULT([installing pkgconf spkg])], [ + ], [ dnl the following as needed as long as Sage creates .pc files during build and/or configure AC_SUBST(SAGE_PKG_CONFIG_PATH, ['$SAGE_LOCAL/lib/pkgconfig']) - AC_MSG_RESULT([using pkg-config from the system]) ]) ]) From 39db606249b7e67e48425328e2cee545a3e88701 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 8 Oct 2023 17:38:40 -0700 Subject: [PATCH 079/216] README.md: Single backticks are enough --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index fa6bd2f2a11..533e7ac54c7 100644 --- a/README.md +++ b/README.md @@ -321,13 +321,13 @@ in the Installation Guide. Notable options for Sage developers are the following: - - Use the option `--config-cache` to have ``configure`` + - Use the option `--config-cache` to have `configure` keep a disk cache of configuration values. This gives a nice speedup when trying out ticket branches that make package upgrades, which involves automatic re-runs of the configuration step. - Use the option `--enable-ccache` to have Sage install and use the - optional package ``ccache``, which is preconfigured to keep a + optional package `ccache`, which is preconfigured to keep a disk cache of object files created from source files. This can give a great speedup when switching between different branches, at the expense of disk space use. From c8c5526ef8e69079b72d463cc03ac5584c17506b Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 8 Oct 2023 19:23:56 -0700 Subject: [PATCH 080/216] .github/workflows/ci-linux.yml: Improve comments --- .github/workflows/ci-linux.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci-linux.yml b/.github/workflows/ci-linux.yml index 8c422cb905e..22df4aa0fd5 100644 --- a/.github/workflows/ci-linux.yml +++ b/.github/workflows/ci-linux.yml @@ -34,8 +34,7 @@ permissions: jobs: - # The default platform used by build.yml etc. - + # standard-pre for the default platform (used by build.yml etc.) default-pre: uses: ./.github/workflows/docker.yml with: @@ -49,6 +48,7 @@ jobs: ["standard"] docker_push_repository: ghcr.io/${{ github.repository }}/ + # standard for the default platform (used by build.yml etc.) default: if: ${{ success() || failure() }} needs: [default-pre] From d8befd87690157715a23599affdecab5c970d818 Mon Sep 17 00:00:00 2001 From: Saatvik Rao Date: Thu, 28 Sep 2023 15:40:02 +0530 Subject: [PATCH 081/216] added induced minor function to graph algorithms --- src/sage/graphs/graph.py | 196 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 196 insertions(+) diff --git a/src/sage/graphs/graph.py b/src/sage/graphs/graph.py index 14d8789bc63..689a4480810 100644 --- a/src/sage/graphs/graph.py +++ b/src/sage/graphs/graph.py @@ -5059,6 +5059,202 @@ def minor(self, H, solver=None, verbose=0, *, integrality_tolerance=1e-3): return rs_dict + def induced_minor(self, H, solver=None, verbose=0, integrality_tolerance=1e-10): + r""" + Returns an induced minor isomorphic to `H` if it exists. + + We say that a graph `G` has an induced `H`-minor (or that it has a + graph isomorphic to `H` as an induced minor), if `H` can be obtained + from an induced subgraph of `G` by contracting edges. Otherwise, `G` is + said to be `H`-induced minor-free. + + For more information, see the :wikipedia:`Minor_(graph_theory)`. + + INPUT: + + - ``H`` -- The induced minor to find for in the current graph. + + - ``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. + + - ``integrality_tolerance`` -- float; parameter for use with MILP + solvers over an inexact base ring; see + :meth:`MixedIntegerLinearProgram.get_values`. + + OUTPUT: + + A dictionary associating to each vertex of `H` the set of vertices in + the current graph representing it. + + ALGORITHM: + + Mixed Integer Linear Programming (MILP) is used to find the minor. The + algorithm is described in [KKT2006]_. + + COMPLEXITY: + + Theoretically, when `H` is fixed, testing for the existence of a induced + minor of `H` is polynomial. The known algorithms are highly exponential in + `H`, though. + + .. NOTE:: + + This function can be expected to be *very* slow, especially where + the induced minor does not exist. + + EXAMPLES: + + Trying to find an induced minor isomorphic to `K_4` in the `4\times 4` grid:: + + sage: # needs sage.numerical.mip + sage: g = graphs.GridGraph([4,4]) + sage: h = graphs.CompleteGraph(4) + sage: L = g.induced_minor(h) + sage: gg = g.subgraph(flatten(L.values(), max_level = 1)) + sage: _ = [gg.merge_vertices(l) for l in L.values() if len(l)>1] + sage: gg.is_isomorphic(h) + True + + Trying to find an induced minor for a graph with a C6 cycle:: + + sage: import random + sage: g = Graph() + sage: cycle_vertices = [g.add_vertex() for _ in range(6)] + sage: for i in range(6): # Connect the vertices to form a C6 cycle + ....: g.add_edge(cycle_vertices[i], cycle_vertices[(i + 1) % 6]) + sage: num_additional_vertices = random.randint(10, 30) # Add a random number of additional vertices + sage: additional_vertices = [g.add_vertex() for _ in range(num_additional_vertices)] + sage: for vertex in additional_vertices: # Connect the additional vertices to the cycle randomly + ....: random_cycle_vertex = random.choice(cycle_vertices) + ....: g.add_edge(random_cycle_vertex, vertex) + sage: h = Graph([(i, (i + 1) % 5) for i in range(5)]) # Create a graph with 5 vertices forming a C5 cycle + sage: L = g.induced_minor(h) + sage: gg = g.subgraph(flatten(L.values(), max_level = 1)) + sage: _ = [gg.merge_vertices(l) for l in L.values() if len(l)>1] + sage: gg.is_isomorphic(h) + True + + TESTS:: + + sage: g = Graph() + sage: g.add_edges([(0, 1), (0, 2), (1, 2), (2, 3), (3, 4), (3, 5), (4, 5), (6, 5)]) + sage: h = Graph() + sage: h.add_edges([(9, 10), (9, 11), (9, 12), (9, 13)]) + sage: l = g.induced_minor(h) + Traceback (most recent call last): + ... + ValueError: This graph has no induced minor isomorphic to H ! + + sage: g = Graph() + sage: g.add_edges([(0, 1), (0, 2), (1, 2), (2, 3), (3, 4), (3, 5), (4, 5), (6, 5)]) + sage: h = Graph() + sage: h.add_edges([(7, 8), (8, 9), (9, 10), (10, 11)]) + sage: L = g.induced_minor(h) + sage: gg = g.subgraph(flatten(L.values(), max_level = 1)) + sage: _ = [gg.merge_vertices(l) for l in L.values() if len(l)>1] + sage: gg.is_isomorphic(h) + True + + """ + self._scream_if_not_simple() + H._scream_if_not_simple() + from sage.numerical.mip import MixedIntegerLinearProgram, MIPSolverException + p = MixedIntegerLinearProgram(solver=solver) + + # We use frozenset((u, v)) to avoid confusion between (u, v) and (v, u) + + # rs = Representative set of a vertex + # for h in H, v in G is such that rs[h,v] == 1 if and only if v + # is a representative of h in self + rs = p.new_variable(binary=True) + + for v in self: + p.add_constraint(p.sum(rs[h, v] for h in H), max=1) + + # We ensure that the set of representatives of a + # vertex h contains a tree, and thus is connected + + # edges represents the edges of the tree + edges = p.new_variable(binary=True) + + # there can be a edge for h between two vertices + # only if those vertices represent h + for u, v in self.edge_iterator(labels=None): + fuv = frozenset((u, v)) + for h in H: + p.add_constraint(edges[h, fuv] - rs[h, u], max=0) + p.add_constraint(edges[h, fuv] - rs[h, v], max=0) + + # The number of edges of the tree in h is exactly the cardinal + # of its representative set minus 1 + + for h in H: + p.add_constraint(p.sum(edges[h, frozenset(e)] for e in self.edge_iterator(labels=None)) + - p.sum(rs[h, v] for v in self), min=-1, max=-1) + + # a tree has no cycle + epsilon = 1/(5*Integer(self.order())) + r_edges = p.new_variable(nonnegative=True) + + for h in H: + for u, v in self.edge_iterator(labels=None): + p.add_constraint(r_edges[h, (u, v)] + r_edges[h, (v, u)] - edges[h, frozenset((u, v))], min=0) + + for v in self: + p.add_constraint(p.sum(r_edges[h, (u, v)] for u in self.neighbor_iterator(v)), max=1-epsilon) + + # Once the representative sets are described, we must ensure + # there are arcs corresponding to those of H between them + h_edges = p.new_variable(nonnegative=True) + + for h1, h2 in H.edge_iterator(labels=None): + + for v1, v2 in self.edge_iterator(labels=None): + fv1v2 = frozenset((v1, v2)) + p.add_constraint(h_edges[(h1, h2), fv1v2] - rs[h2, v2], max=0) + p.add_constraint(h_edges[(h1, h2), fv1v2] - rs[h1, v1], max=0) + + p.add_constraint(h_edges[(h2, h1), fv1v2] - rs[h1, v2], max=0) + p.add_constraint(h_edges[(h2, h1), fv1v2] - rs[h2, v1], max=0) + + p.add_constraint(p.sum(h_edges[(h1, h2), frozenset(e)] + h_edges[(h2, h1), frozenset(e)] + for e in self.edge_iterator(labels=None)), min=1) + + + # condition for induced subgraph ensures that if there + # doesnt exist an edge(h1, h2) in H then there should + # not be an edge between representative sets of h1 and h2 in G + for h1 in H: + for h2 in H: + if not h1 == h2 and not H.has_edge(h1, h2): + for v1, v2 in self.edge_iterator(labels=None): + expr2 = rs[h1, v1] + rs[h2, v2] + p.add_constraint(expr2, max=1) + + + p.set_objective(None) + + try: + p.solve(log=verbose) + except MIPSolverException: + raise ValueError("This graph has no induced minor isomorphic to H !") + + rs = p.get_values(rs) + + rs_dict = {} + for h in H: + rs_dict[h] = [v for v in self if rs[h, v]] + + return rs_dict + # Convexity @doc_index("Algorithmically hard stuff") From 49745af9b6cb5e112cc89e05dc89e27a562d1d70 Mon Sep 17 00:00:00 2001 From: Saatvik Rao Date: Wed, 4 Oct 2023 01:13:46 +0530 Subject: [PATCH 082/216] unified the minor and induced minor functions --- src/sage/graphs/graph.py | 185 ++++++--------------------------------- 1 file changed, 25 insertions(+), 160 deletions(-) diff --git a/src/sage/graphs/graph.py b/src/sage/graphs/graph.py index 689a4480810..484d1b668f3 100644 --- a/src/sage/graphs/graph.py +++ b/src/sage/graphs/graph.py @@ -4891,9 +4891,9 @@ def independent_set_of_representatives(self, family, solver=None, verbose=0, return repr @doc_index("Algorithmically hard stuff") - def minor(self, H, solver=None, verbose=0, *, integrality_tolerance=1e-3): + def minor(self, H, solver=None, verbose=0, *, integrality_tolerance=1e-3, induced=False): r""" - Return the vertices of a minor isomorphic to `H` in the current graph. + Return the vertices of a minor isomorphic to `H` in the current graph for induced=False We say that a graph `G` has a `H`-minor (or that it has a graph isomorphic to `H` as a minor), if for all `h\in H`, there exist disjoint @@ -4901,6 +4901,13 @@ def minor(self, H, solver=None, verbose=0, *, integrality_tolerance=1e-3): been merged to create a new graph `G'`, this new graph contains `H` as a subgraph. + Returns an induced minor isomorphic to `H` if it exists for induced=True + + We say that a graph `G` has an induced `H`-minor (or that it has a + graph isomorphic to `H` as an induced minor), if `H` can be obtained + from an induced subgraph of `G` by contracting edges. Otherwise, `G` is + said to be `H`-induced minor-free. + For more information, see the :wikipedia:`Minor_(graph_theory)`. INPUT: @@ -4922,6 +4929,9 @@ def minor(self, H, solver=None, verbose=0, *, integrality_tolerance=1e-3): solvers over an inexact base ring; see :meth:`MixedIntegerLinearProgram.get_values`. + - ``induced`` -- boolean (default: ``False``); if ``True``, returns an + induced minor isomorphic to `H` if it exists, and ``None`` otherwise. + OUTPUT: A dictionary associating to each vertex of `H` the set of vertices in @@ -4979,149 +4989,6 @@ def minor(self, H, solver=None, verbose=0, *, integrality_tolerance=1e-3): Traceback (most recent call last): ... ValueError: This graph has no minor isomorphic to H ! - """ - self._scream_if_not_simple() - H._scream_if_not_simple() - from sage.numerical.mip import MixedIntegerLinearProgram, MIPSolverException - p = MixedIntegerLinearProgram(solver=solver) - - # We use frozenset((u, v)) to avoid confusion between (u, v) and (v, u) - - # rs = Representative set of a vertex - # for h in H, v in G is such that rs[h,v] == 1 if and only if v - # is a representative of h in self - rs = p.new_variable(binary=True) - - for v in self: - p.add_constraint(p.sum(rs[h, v] for h in H), max=1) - - # We ensure that the set of representatives of a - # vertex h contains a tree, and thus is connected - - # edges represents the edges of the tree - edges = p.new_variable(binary=True) - - # there can be a edge for h between two vertices - # only if those vertices represent h - for u, v in self.edge_iterator(labels=None): - fuv = frozenset((u, v)) - for h in H: - p.add_constraint(edges[h, fuv] - rs[h, u], max=0) - p.add_constraint(edges[h, fuv] - rs[h, v], max=0) - - # The number of edges of the tree in h is exactly the cardinal - # of its representative set minus 1 - - for h in H: - p.add_constraint(p.sum(edges[h, frozenset(e)] for e in self.edge_iterator(labels=None)) - - p.sum(rs[h, v] for v in self), min=-1, max=-1) - - # a tree has no cycle - epsilon = 1/(5*Integer(self.order())) - r_edges = p.new_variable(nonnegative=True) - - for h in H: - for u, v in self.edge_iterator(labels=None): - p.add_constraint(r_edges[h, (u, v)] + r_edges[h, (v, u)] - edges[h, frozenset((u, v))], min=0) - - for v in self: - p.add_constraint(p.sum(r_edges[h, (u, v)] for u in self.neighbor_iterator(v)), max=1-epsilon) - - # Once the representative sets are described, we must ensure - # there are arcs corresponding to those of H between them - h_edges = p.new_variable(nonnegative=True) - - for h1, h2 in H.edge_iterator(labels=None): - - for v1, v2 in self.edge_iterator(labels=None): - fv1v2 = frozenset((v1, v2)) - p.add_constraint(h_edges[(h1, h2), fv1v2] - rs[h2, v2], max=0) - p.add_constraint(h_edges[(h1, h2), fv1v2] - rs[h1, v1], max=0) - - p.add_constraint(h_edges[(h2, h1), fv1v2] - rs[h1, v2], max=0) - p.add_constraint(h_edges[(h2, h1), fv1v2] - rs[h2, v1], max=0) - - p.add_constraint(p.sum(h_edges[(h1, h2), frozenset(e)] + h_edges[(h2, h1), frozenset(e)] - for e in self.edge_iterator(labels=None)), min=1) - - p.set_objective(None) - - try: - p.solve(log=verbose) - except MIPSolverException: - raise ValueError("This graph has no minor isomorphic to H !") - - rs = p.get_values(rs, convert=bool, tolerance=integrality_tolerance) - - rs_dict = {} - for h in H: - rs_dict[h] = [v for v in self if rs[h, v]] - - return rs_dict - - def induced_minor(self, H, solver=None, verbose=0, integrality_tolerance=1e-10): - r""" - Returns an induced minor isomorphic to `H` if it exists. - - We say that a graph `G` has an induced `H`-minor (or that it has a - graph isomorphic to `H` as an induced minor), if `H` can be obtained - from an induced subgraph of `G` by contracting edges. Otherwise, `G` is - said to be `H`-induced minor-free. - - For more information, see the :wikipedia:`Minor_(graph_theory)`. - - INPUT: - - - ``H`` -- The induced minor to find for in the current graph. - - - ``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. - - - ``integrality_tolerance`` -- float; parameter for use with MILP - solvers over an inexact base ring; see - :meth:`MixedIntegerLinearProgram.get_values`. - - OUTPUT: - - A dictionary associating to each vertex of `H` the set of vertices in - the current graph representing it. - - ALGORITHM: - - Mixed Integer Linear Programming (MILP) is used to find the minor. The - algorithm is described in [KKT2006]_. - - COMPLEXITY: - - Theoretically, when `H` is fixed, testing for the existence of a induced - minor of `H` is polynomial. The known algorithms are highly exponential in - `H`, though. - - .. NOTE:: - - This function can be expected to be *very* slow, especially where - the induced minor does not exist. - - EXAMPLES: - - Trying to find an induced minor isomorphic to `K_4` in the `4\times 4` grid:: - - sage: # needs sage.numerical.mip - sage: g = graphs.GridGraph([4,4]) - sage: h = graphs.CompleteGraph(4) - sage: L = g.induced_minor(h) - sage: gg = g.subgraph(flatten(L.values(), max_level = 1)) - sage: _ = [gg.merge_vertices(l) for l in L.values() if len(l)>1] - sage: gg.is_isomorphic(h) - True Trying to find an induced minor for a graph with a C6 cycle:: @@ -5136,7 +5003,7 @@ def induced_minor(self, H, solver=None, verbose=0, integrality_tolerance=1e-10): ....: random_cycle_vertex = random.choice(cycle_vertices) ....: g.add_edge(random_cycle_vertex, vertex) sage: h = Graph([(i, (i + 1) % 5) for i in range(5)]) # Create a graph with 5 vertices forming a C5 cycle - sage: L = g.induced_minor(h) + sage: L = g.minor(h, induced=True)) sage: gg = g.subgraph(flatten(L.values(), max_level = 1)) sage: _ = [gg.merge_vertices(l) for l in L.values() if len(l)>1] sage: gg.is_isomorphic(h) @@ -5148,7 +5015,7 @@ def induced_minor(self, H, solver=None, verbose=0, integrality_tolerance=1e-10): sage: g.add_edges([(0, 1), (0, 2), (1, 2), (2, 3), (3, 4), (3, 5), (4, 5), (6, 5)]) sage: h = Graph() sage: h.add_edges([(9, 10), (9, 11), (9, 12), (9, 13)]) - sage: l = g.induced_minor(h) + sage: l = g.minor(h, induced=True) Traceback (most recent call last): ... ValueError: This graph has no induced minor isomorphic to H ! @@ -5157,12 +5024,11 @@ def induced_minor(self, H, solver=None, verbose=0, integrality_tolerance=1e-10): sage: g.add_edges([(0, 1), (0, 2), (1, 2), (2, 3), (3, 4), (3, 5), (4, 5), (6, 5)]) sage: h = Graph() sage: h.add_edges([(7, 8), (8, 9), (9, 10), (10, 11)]) - sage: L = g.induced_minor(h) + sage: L = g.minor(h, induced=True) sage: gg = g.subgraph(flatten(L.values(), max_level = 1)) sage: _ = [gg.merge_vertices(l) for l in L.values() if len(l)>1] sage: gg.is_isomorphic(h) True - """ self._scream_if_not_simple() H._scream_if_not_simple() @@ -5227,27 +5093,26 @@ def induced_minor(self, H, solver=None, verbose=0, integrality_tolerance=1e-10): p.add_constraint(p.sum(h_edges[(h1, h2), frozenset(e)] + h_edges[(h2, h1), frozenset(e)] for e in self.edge_iterator(labels=None)), min=1) - - + + # if induced is True # condition for induced subgraph ensures that if there # doesnt exist an edge(h1, h2) in H then there should # not be an edge between representative sets of h1 and h2 in G - for h1 in H: - for h2 in H: - if not h1 == h2 and not H.has_edge(h1, h2): - for v1, v2 in self.edge_iterator(labels=None): - expr2 = rs[h1, v1] + rs[h2, v2] - p.add_constraint(expr2, max=1) - + if (induced): + for h1 in H: + for h2 in H: + if not h1 == h2 and not H.has_edge(h1, h2): + for v1, v2 in self.edge_iterator(labels=None): + p.add_constraint(rs[h1, v1] + rs[h2, v2], max=1) p.set_objective(None) try: p.solve(log=verbose) except MIPSolverException: - raise ValueError("This graph has no induced minor isomorphic to H !") + raise ValueError("This graph has no minor isomorphic to H !") - rs = p.get_values(rs) + rs = p.get_values(rs, convert=bool, tolerance=integrality_tolerance) rs_dict = {} for h in H: From 83a3007dd4f1eca6dce238193af2e104d0e3b4da Mon Sep 17 00:00:00 2001 From: Saatvik Rao Date: Wed, 4 Oct 2023 01:20:54 +0530 Subject: [PATCH 083/216] simplified test cases --- src/sage/graphs/graph.py | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/src/sage/graphs/graph.py b/src/sage/graphs/graph.py index 484d1b668f3..7d4edc44087 100644 --- a/src/sage/graphs/graph.py +++ b/src/sage/graphs/graph.py @@ -4992,18 +4992,11 @@ def minor(self, H, solver=None, verbose=0, *, integrality_tolerance=1e-3, induce Trying to find an induced minor for a graph with a C6 cycle:: - sage: import random - sage: g = Graph() - sage: cycle_vertices = [g.add_vertex() for _ in range(6)] - sage: for i in range(6): # Connect the vertices to form a C6 cycle - ....: g.add_edge(cycle_vertices[i], cycle_vertices[(i + 1) % 6]) - sage: num_additional_vertices = random.randint(10, 30) # Add a random number of additional vertices - sage: additional_vertices = [g.add_vertex() for _ in range(num_additional_vertices)] - sage: for vertex in additional_vertices: # Connect the additional vertices to the cycle randomly - ....: random_cycle_vertex = random.choice(cycle_vertices) - ....: g.add_edge(random_cycle_vertex, vertex) - sage: h = Graph([(i, (i + 1) % 5) for i in range(5)]) # Create a graph with 5 vertices forming a C5 cycle - sage: L = g.minor(h, induced=True)) + sage: g = graphs.CycleGraph(6) # Create a graph with 6 vertices forming a C6 cycle + sage: for i in random.randint(10, 30): + ....: g.add_edge(random.randint(0, 5), i) + sage: h = graphs.CycleGraph(5) # Create a graph with 5 vertices forming a C5 cycle + sage: L = g.minor(h, induced=True) sage: gg = g.subgraph(flatten(L.values(), max_level = 1)) sage: _ = [gg.merge_vertices(l) for l in L.values() if len(l)>1] sage: gg.is_isomorphic(h) From 764c2afb684b58a79a7fb41a84293125970917b0 Mon Sep 17 00:00:00 2001 From: Saatvik Rao Date: Thu, 5 Oct 2023 00:11:45 +0530 Subject: [PATCH 084/216] minor fixes in function and tests --- src/sage/graphs/graph.py | 41 +++++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/src/sage/graphs/graph.py b/src/sage/graphs/graph.py index 7d4edc44087..6732bd422eb 100644 --- a/src/sage/graphs/graph.py +++ b/src/sage/graphs/graph.py @@ -4891,9 +4891,9 @@ def independent_set_of_representatives(self, family, solver=None, verbose=0, return repr @doc_index("Algorithmically hard stuff") - def minor(self, H, solver=None, verbose=0, *, integrality_tolerance=1e-3, induced=False): + def minor(self, H, solver=None, verbose=0, induced=False, *, integrality_tolerance=1e-3): r""" - Return the vertices of a minor isomorphic to `H` in the current graph for induced=False + Return the vertices of a minor isomorphic to `H` in the current graph. We say that a graph `G` has a `H`-minor (or that it has a graph isomorphic to `H` as a minor), if for all `h\in H`, there exist disjoint @@ -4901,7 +4901,8 @@ def minor(self, H, solver=None, verbose=0, *, integrality_tolerance=1e-3, induce been merged to create a new graph `G'`, this new graph contains `H` as a subgraph. - Returns an induced minor isomorphic to `H` if it exists for induced=True + When parameter ``induced`` is ``True``, this method returns an induced minor + isomorphic to `H`, if it exists. We say that a graph `G` has an induced `H`-minor (or that it has a graph isomorphic to `H` as an induced minor), if `H` can be obtained @@ -4930,7 +4931,7 @@ def minor(self, H, solver=None, verbose=0, *, integrality_tolerance=1e-3, induce :meth:`MixedIntegerLinearProgram.get_values`. - ``induced`` -- boolean (default: ``False``); if ``True``, returns an - induced minor isomorphic to `H` if it exists, and ``None`` otherwise. + induced minor isomorphic to `H` if it exists, and ``ValueError`` otherwise. OUTPUT: @@ -5004,19 +5005,22 @@ def minor(self, H, solver=None, verbose=0, *, integrality_tolerance=1e-3, induce TESTS:: - sage: g = Graph() - sage: g.add_edges([(0, 1), (0, 2), (1, 2), (2, 3), (3, 4), (3, 5), (4, 5), (6, 5)]) - sage: h = Graph() - sage: h.add_edges([(9, 10), (9, 11), (9, 12), (9, 13)]) + sage: g = Graph([(0, 1), (0, 2), (1, 2), (2, 3), (3, 4), (3, 5), (4, 5), (6, 5)]) + sage: h = Graph([(9, 10), (9, 11), (9, 12), (9, 13)]) sage: l = g.minor(h, induced=True) Traceback (most recent call last): ... ValueError: This graph has no induced minor isomorphic to H ! - - sage: g = Graph() - sage: g.add_edges([(0, 1), (0, 2), (1, 2), (2, 3), (3, 4), (3, 5), (4, 5), (6, 5)]) - sage: h = Graph() - sage: h.add_edges([(7, 8), (8, 9), (9, 10), (10, 11)]) + + sage: # induced minor does not exist, but minor does + sage: g = Graph([(0, 1), (0, 2), (1, 2), (2, 3), (3, 4), (3, 5), (4, 5), (6, 5)]) + sage: h = Graph([(9, 10), (9, 11), (9, 12), (9, 13)]) + sage: l = g.minor(h, induced=False) + sage: print("minor exists") + minor exists + + sage: g = Graph([(0, 1), (0, 2), (1, 2), (2, 3), (3, 4), (3, 5), (4, 5), (6, 5)]) + sage: h = Graph([(7, 8), (8, 9), (9, 10), (10, 11)]) sage: L = g.minor(h, induced=True) sage: gg = g.subgraph(flatten(L.values(), max_level = 1)) sage: _ = [gg.merge_vertices(l) for l in L.values() if len(l)>1] @@ -5091,12 +5095,11 @@ def minor(self, H, solver=None, verbose=0, *, integrality_tolerance=1e-3, induce # condition for induced subgraph ensures that if there # doesnt exist an edge(h1, h2) in H then there should # not be an edge between representative sets of h1 and h2 in G - if (induced): - for h1 in H: - for h2 in H: - if not h1 == h2 and not H.has_edge(h1, h2): - for v1, v2 in self.edge_iterator(labels=None): - p.add_constraint(rs[h1, v1] + rs[h2, v2], max=1) + if induced: + for h1, h2 in H.complement().edge_iterator(labels=False): + for v1, v2 in self.edge_iterator(labels=False): + p.add_constraint(rs[h1, v1] + rs[h2, v2], max=1) + p.add_constraint(rs[h2, v1] + rs[h1, v2], max=1) p.set_objective(None) From 18d5246a02fd3ced944a48cce0ce7c46f45fc508 Mon Sep 17 00:00:00 2001 From: Saatvik Rao Date: Fri, 6 Oct 2023 15:07:59 +0530 Subject: [PATCH 085/216] minor changes for code quality --- src/sage/graphs/graph.py | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/src/sage/graphs/graph.py b/src/sage/graphs/graph.py index 6732bd422eb..a46ede59c7e 100644 --- a/src/sage/graphs/graph.py +++ b/src/sage/graphs/graph.py @@ -4931,7 +4931,7 @@ def minor(self, H, solver=None, verbose=0, induced=False, *, integrality_toleran :meth:`MixedIntegerLinearProgram.get_values`. - ``induced`` -- boolean (default: ``False``); if ``True``, returns an - induced minor isomorphic to `H` if it exists, and ``ValueError`` otherwise. + induced minor isomorphic to `H` if it exists, and ``:class:`ValueError``` otherwise. OUTPUT: @@ -5004,20 +5004,15 @@ def minor(self, H, solver=None, verbose=0, induced=False, *, integrality_toleran True TESTS:: - + + sage: # a graph `g` may have minor but no induced minor isomorphic to given graph `h` sage: g = Graph([(0, 1), (0, 2), (1, 2), (2, 3), (3, 4), (3, 5), (4, 5), (6, 5)]) sage: h = Graph([(9, 10), (9, 11), (9, 12), (9, 13)]) + sage: l = g.minor(h, induced=False) sage: l = g.minor(h, induced=True) Traceback (most recent call last): ... ValueError: This graph has no induced minor isomorphic to H ! - - sage: # induced minor does not exist, but minor does - sage: g = Graph([(0, 1), (0, 2), (1, 2), (2, 3), (3, 4), (3, 5), (4, 5), (6, 5)]) - sage: h = Graph([(9, 10), (9, 11), (9, 12), (9, 13)]) - sage: l = g.minor(h, induced=False) - sage: print("minor exists") - minor exists sage: g = Graph([(0, 1), (0, 2), (1, 2), (2, 3), (3, 4), (3, 5), (4, 5), (6, 5)]) sage: h = Graph([(7, 8), (8, 9), (9, 10), (10, 11)]) @@ -5106,7 +5101,10 @@ def minor(self, H, solver=None, verbose=0, induced=False, *, integrality_toleran try: p.solve(log=verbose) except MIPSolverException: - raise ValueError("This graph has no minor isomorphic to H !") + if induced: + raise ValueError("This graph has no induced minor isomorphic to H !") + else: + raise ValueError("This graph has no minor isomorphic to H !") rs = p.get_values(rs, convert=bool, tolerance=integrality_tolerance) From ccd25f1d5f3c5a5d5e6564c823b94dedddb77a94 Mon Sep 17 00:00:00 2001 From: Saatvik Rao Date: Fri, 6 Oct 2023 15:20:50 +0530 Subject: [PATCH 086/216] minor changes for code quality --- 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 a46ede59c7e..1ac3553f7bf 100644 --- a/src/sage/graphs/graph.py +++ b/src/sage/graphs/graph.py @@ -4931,7 +4931,7 @@ def minor(self, H, solver=None, verbose=0, induced=False, *, integrality_toleran :meth:`MixedIntegerLinearProgram.get_values`. - ``induced`` -- boolean (default: ``False``); if ``True``, returns an - induced minor isomorphic to `H` if it exists, and ``:class:`ValueError``` otherwise. + induced minor isomorphic to `H` if it exists, and :class:`ValueError` otherwise. OUTPUT: From 8941758e39cf0db6ef3be7b197e719404f87aa1b Mon Sep 17 00:00:00 2001 From: Saatvik Rao Date: Fri, 6 Oct 2023 15:29:48 +0530 Subject: [PATCH 087/216] changes for python code style --- src/sage/graphs/graph.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/sage/graphs/graph.py b/src/sage/graphs/graph.py index 1ac3553f7bf..10326283037 100644 --- a/src/sage/graphs/graph.py +++ b/src/sage/graphs/graph.py @@ -4893,7 +4893,7 @@ def independent_set_of_representatives(self, family, solver=None, verbose=0, @doc_index("Algorithmically hard stuff") def minor(self, H, solver=None, verbose=0, induced=False, *, integrality_tolerance=1e-3): r""" - Return the vertices of a minor isomorphic to `H` in the current graph. + Return the vertices of a minor isomorphic to `H` in the current graph. We say that a graph `G` has a `H`-minor (or that it has a graph isomorphic to `H` as a minor), if for all `h\in H`, there exist disjoint @@ -4907,7 +4907,7 @@ def minor(self, H, solver=None, verbose=0, induced=False, *, integrality_toleran We say that a graph `G` has an induced `H`-minor (or that it has a graph isomorphic to `H` as an induced minor), if `H` can be obtained from an induced subgraph of `G` by contracting edges. Otherwise, `G` is - said to be `H`-induced minor-free. + said to be `H`-induced minor-free. For more information, see the :wikipedia:`Minor_(graph_theory)`. @@ -4931,7 +4931,7 @@ def minor(self, H, solver=None, verbose=0, induced=False, *, integrality_toleran :meth:`MixedIntegerLinearProgram.get_values`. - ``induced`` -- boolean (default: ``False``); if ``True``, returns an - induced minor isomorphic to `H` if it exists, and :class:`ValueError` otherwise. + induced minor isomorphic to `H` if it exists, and :class:`ValueError` otherwise. OUTPUT: @@ -4997,9 +4997,9 @@ def minor(self, H, solver=None, verbose=0, induced=False, *, integrality_toleran sage: for i in random.randint(10, 30): ....: g.add_edge(random.randint(0, 5), i) sage: h = graphs.CycleGraph(5) # Create a graph with 5 vertices forming a C5 cycle - sage: L = g.minor(h, induced=True) - sage: gg = g.subgraph(flatten(L.values(), max_level = 1)) - sage: _ = [gg.merge_vertices(l) for l in L.values() if len(l)>1] + sage: L = g.minor(h, induced=True) + sage: gg = g.subgraph(flatten(L.values(), max_level = 1)) + sage: _ = [gg.merge_vertices(l) for l in L.values() if len(l)>1] sage: gg.is_isomorphic(h) True From c255d4bb8b52569f5b52bea8e896898f46bcdd46 Mon Sep 17 00:00:00 2001 From: Saatvik Rao Date: Sat, 7 Oct 2023 08:56:09 +0530 Subject: [PATCH 088/216] fixing minor bugs --- src/sage/graphs/graph.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/graphs/graph.py b/src/sage/graphs/graph.py index 10326283037..25bbeea0657 100644 --- a/src/sage/graphs/graph.py +++ b/src/sage/graphs/graph.py @@ -4997,8 +4997,8 @@ def minor(self, H, solver=None, verbose=0, induced=False, *, integrality_toleran sage: for i in random.randint(10, 30): ....: g.add_edge(random.randint(0, 5), i) sage: h = graphs.CycleGraph(5) # Create a graph with 5 vertices forming a C5 cycle - sage: L = g.minor(h, induced=True) - sage: gg = g.subgraph(flatten(L.values(), max_level = 1)) + sage: L = g.minor(h, induced=True) + sage: gg = g.subgraph(flatten(L.values(), max_level = 1)) sage: _ = [gg.merge_vertices(l) for l in L.values() if len(l)>1] sage: gg.is_isomorphic(h) True From 226c97a9069f941937d0241351a727852d4c9638 Mon Sep 17 00:00:00 2001 From: Saatvik Rao Date: Mon, 9 Oct 2023 11:40:14 +0530 Subject: [PATCH 089/216] minor changes in code style and doctests --- src/sage/graphs/graph.py | 33 ++++++++++++++++++++------------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/src/sage/graphs/graph.py b/src/sage/graphs/graph.py index 25bbeea0657..718dbdad745 100644 --- a/src/sage/graphs/graph.py +++ b/src/sage/graphs/graph.py @@ -4901,7 +4901,7 @@ def minor(self, H, solver=None, verbose=0, induced=False, *, integrality_toleran been merged to create a new graph `G'`, this new graph contains `H` as a subgraph. - When parameter ``induced`` is ``True``, this method returns an induced minor + When parameter ``induced`` is ``True``, this method returns an induced minor isomorphic to `H`, if it exists. We say that a graph `G` has an induced `H`-minor (or that it has a @@ -4931,7 +4931,8 @@ def minor(self, H, solver=None, verbose=0, induced=False, *, integrality_toleran :meth:`MixedIntegerLinearProgram.get_values`. - ``induced`` -- boolean (default: ``False``); if ``True``, returns an - induced minor isomorphic to `H` if it exists, and :class:`ValueError` otherwise. + induced minor isomorphic to `H` if it exists, and raises a + :class:`ValueError` otherwise. OUTPUT: @@ -4991,21 +4992,24 @@ def minor(self, H, solver=None, verbose=0, induced=False, *, integrality_toleran ... ValueError: This graph has no minor isomorphic to H ! - Trying to find an induced minor for a graph with a C6 cycle:: + Trying to find an induced minor isomorphic to `C_5` in a graph + containing an induced `C_6`:: - sage: g = graphs.CycleGraph(6) # Create a graph with 6 vertices forming a C6 cycle - sage: for i in random.randint(10, 30): - ....: g.add_edge(random.randint(0, 5), i) - sage: h = graphs.CycleGraph(5) # Create a graph with 5 vertices forming a C5 cycle - sage: L = g.minor(h, induced=True) - sage: gg = g.subgraph(flatten(L.values(), max_level = 1)) - sage: _ = [gg.merge_vertices(l) for l in L.values() if len(l)>1] + sage: g = graphs.CycleGraph(6) + sage: for i in range(randint(10, 30)): + ....: g.add_edge(randint(0, 5), g.add_vertex()) + sage: h = graphs.CycleGraph(5) + sage: L = g.minor(h, induced=True) + sage: gg = g.subgraph(flatten(L.values(), max_level=1)) + sage: _ = [gg.merge_vertices(l) for l in L.values() if len(l) > 1] sage: gg.is_isomorphic(h) True TESTS:: - sage: # a graph `g` may have minor but no induced minor isomorphic to given graph `h` + A graph `g` may have a minor isomorphic to a given graph `h` but no + induced minor isomorphic to `h`:: + sage: g = Graph([(0, 1), (0, 2), (1, 2), (2, 3), (3, 4), (3, 5), (4, 5), (6, 5)]) sage: h = Graph([(9, 10), (9, 11), (9, 12), (9, 13)]) sage: l = g.minor(h, induced=False) @@ -5014,11 +5018,14 @@ def minor(self, H, solver=None, verbose=0, induced=False, *, integrality_toleran ... ValueError: This graph has no induced minor isomorphic to H ! + Checking that the returned induced minor is isomorphic to the given + graph:: + sage: g = Graph([(0, 1), (0, 2), (1, 2), (2, 3), (3, 4), (3, 5), (4, 5), (6, 5)]) sage: h = Graph([(7, 8), (8, 9), (9, 10), (10, 11)]) sage: L = g.minor(h, induced=True) - sage: gg = g.subgraph(flatten(L.values(), max_level = 1)) - sage: _ = [gg.merge_vertices(l) for l in L.values() if len(l)>1] + sage: gg = g.subgraph(flatten(L.values(), max_level=1)) + sage: _ = [gg.merge_vertices(l) for l in L.values() if len(l) > 1] sage: gg.is_isomorphic(h) True """ From 235ce91795439949e3b86f49f37bc0a72dba740b Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 8 Oct 2023 23:23:18 -0700 Subject: [PATCH 090/216] bootstrap-conda: Only one 'python' line + speed up --- bootstrap-conda | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/bootstrap-conda b/bootstrap-conda index 90d27ab7be7..19e56e3c5fa 100755 --- a/bootstrap-conda +++ b/bootstrap-conda @@ -81,14 +81,13 @@ unset ENABLE_SYSTEM_SITE_PACKAGES [ -n "$BOOTSTRAP_VERBOSE" ] && echo "## Translated to system:" && set | grep SYSTEM_PACKAGES= echo >&2 $0:$LINENO: generate conda environment files -for python_version in 3.9 3.10 3.11; do + ( echo "name: sage-build" echo "channels:" echo " - conda-forge" echo " - nodefaults" echo "dependencies:" - echo " - python=$python_version" for pkg in $SYSTEM_PACKAGES; do echo " - $pkg" done @@ -96,38 +95,38 @@ for python_version in 3.9 3.10 3.11; do for pkg in $BOOTSTRAP_SYSTEM_PACKAGES; do echo " - $pkg" done - ) > environment-$python_version.yml + ) > environment-template.yml ( - sed 's/name: sage-build/name: sage/' environment-$python_version.yml + sed 's/name: sage-build/name: sage/' environment-template.yml echo " # Additional packages providing all dependencies for the Sage library" for pkg in $SAGELIB_SYSTEM_PACKAGES; do echo " - $pkg" done - ) > src/environment-$python_version.yml + ) > src/environment-template.yml ( - cat environment-$python_version.yml + cat environment-template.yml echo " # optional packages" for pkg in $OPTIONAL_SYSTEM_PACKAGES; do echo " - $pkg" done - ) > environment-optional-$python_version.yml + ) > environment-optional-template.yml ( - sed 's/name: sage/name: sage-dev/' src/environment-$python_version.yml + sed 's/name: sage/name: sage-dev/' src/environment-template.yml echo " # Additional dev tools" for pkg in $DEVELOP_SYSTEM_PACKAGES; do echo " - $pkg" done - ) > src/environment-dev-$python_version.yml + ) > src/environment-dev-template.yml ( - cat src/environment-$python_version.yml + cat src/environment-template.yml echo " # optional packages" for pkg in $OPTIONAL_SYSTEM_PACKAGES $SAGELIB_OPTIONAL_SYSTEM_PACKAGES; do echo " - $pkg" done - ) > src/environment-optional-$python_version.yml + ) > src/environment-optional-template.yml ( echo >&4 " - pip:" @@ -152,5 +151,11 @@ for python_version in 3.9 3.10 3.11; do done fi done - ) 4>> src/environment-dev-$python_version.yml 5>> src/environment-optional-$python_version.yml + ) 4>> src/environment-dev-template.yml 5>> src/environment-optional-template.yml + +for f in environment environment-optional src/environment src/environment-optional src/environment-dev; do + for python_version in 3.9 3.10 3.11; do + sed -E 's/^( *- *)python *$/\1python='$python_version'/' $f-template.yml > $f-$python_version.yml + done + rm -f $f-template.yml done From 273296d32a880739d30aacef2f148975487f7380 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Mon, 9 Oct 2023 08:41:04 +0200 Subject: [PATCH 091/216] suggested details --- src/sage/interfaces/gap3.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/sage/interfaces/gap3.py b/src/sage/interfaces/gap3.py index 95cdbad6cf1..602cf525481 100644 --- a/src/sage/interfaces/gap3.py +++ b/src/sage/interfaces/gap3.py @@ -45,7 +45,7 @@ Sage assumes that the command ``gap3`` is in your ``PATH``. If this is not the case, then you can start GAP3 using the following command:: - sage: gap3 = Gap3(command='/usr/local/bin/gap3') #not tested + sage: gap3 = Gap3(command='/usr/local/bin/gap3') # not tested Functionality and Examples -------------------------- @@ -114,7 +114,7 @@ :: - sage: gap3.interact() #not tested + sage: gap3.interact() # not tested --> Switching to Gap3 <-- @@ -122,7 +122,7 @@ #. You can start a new GAP3 session as follows:: - sage: gap3.console() #not tested + sage: gap3.console() # not tested ######## Lehrstuhl D fuer Mathematik ### #### RWTH Aachen @@ -150,7 +150,7 @@ #. The interface also has access to the GAP3 help system:: - sage: gap3.help('help', pager=False) #not tested + sage: gap3.help('help', pager=False) # not tested Help _______________________________________________________... This section describes together with the following sections the GAP @@ -521,13 +521,13 @@ def cputime(self, t=None): sage: # optional - gap3 sage: t = gap3.cputime() - sage: t #random + sage: t # random 0.02 sage: gap3.SymmetricGroup(5).Size() 120 - sage: gap3.cputime() #random + sage: gap3.cputime() # random 0.14999999999999999 - sage: gap3.cputime(t) #random + sage: gap3.cputime(t) # random 0.13 """ if t is not None: @@ -541,7 +541,7 @@ def console(self): EXAMPLES:: - sage: gap3.console() #not tested + sage: gap3.console() # not tested ######## Lehrstuhl D fuer Mathematik ### #### RWTH Aachen @@ -886,7 +886,7 @@ def gap3_console(): EXAMPLES:: - sage: gap3.console() #not tested + sage: gap3.console() # not tested ######## Lehrstuhl D fuer Mathematik ### #### RWTH Aachen From 3950f40b253212bfdaa0e2df63036bd684524e86 Mon Sep 17 00:00:00 2001 From: Dima Pasechnik Date: Sun, 8 Oct 2023 09:54:14 +0100 Subject: [PATCH 092/216] replace wrongly placed sig_on/off pair with sig_check fixes the bug noted in https://github.com/mpmath/mpmath/issues/723 sage: from mpmath import * sage: mp.dps=16 sage: zeta(-0.01 + 1000j) --------------------------------------------------------------------------- SystemError Traceback (most recent call last) Cell In [3], line 1 ----> 1 zeta(-RealNumber('0.01') + ComplexNumber(0, '1000')) File /usr/lib/python3.11/site-packages/mpmath/functions/zeta.py:580, in zeta(ctx, s, a, derivative, method, **kwargs) 578 if ctx.re(s) > 2*ctx.prec and a == 1 and not derivative: 579 return ctx.one + ctx.power(2, -s) --> 580 return +ctx._hurwitz(s, a, d, **kwargs) File /usr/lib/python3.11/site-packages/mpmath/functions/zeta.py:595, in _hurwitz(ctx, s, a, d, **kwargs) 593 print("zeta: Attempting reflection formula") 594 try: --> 595 return _hurwitz_reflection(ctx, s, a, d, atype) 596 except NotImplementedError: 597 pass File /usr/lib/python3.11/site-packages/mpmath/functions/zeta.py:654, in _hurwitz_reflection(ctx, s, a, d, atype) 652 p += shift*q 653 assert 1 <= p <= q --> 654 g = ctx.fsum(ctx.cospi(t/2-2*k*b)*ctx._hurwitz(t,(k,q)) \ 655 for k in range(1,q+1)) 656 g *= 2*ctx.gamma(t)/(2*ctx.pi*q)**t 657 v += g File /mnt/opt/Sage/sage-dev/src/sage/libs/mpmath/ext_main.pyx:767, in sage.libs.mpmath.ext_main.Context.fsum() 765 workopts.rounding = ROUND_D 766 unknown = global_context.zero --> 767 sig_on() 768 try: # Way down, there is a ``finally`` with sig_off() 769 MPF_init(&sre) SystemError: calling remove_from_pari_stack() inside sig_on() --- src/sage/libs/mpmath/ext_main.pyx | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/src/sage/libs/mpmath/ext_main.pyx b/src/sage/libs/mpmath/ext_main.pyx index 845c85234a6..ee8e37bd51c 100644 --- a/src/sage/libs/mpmath/ext_main.pyx +++ b/src/sage/libs/mpmath/ext_main.pyx @@ -19,7 +19,7 @@ from cpython.float cimport * from cpython.complex cimport * from cpython.number cimport * -from cysignals.signals cimport sig_on, sig_off +from cysignals.signals cimport sig_check from sage.ext.stdsage cimport PY_NEW @@ -707,7 +707,6 @@ cdef class Context: False sage: isint(3+2j, gaussian=True) True - """ cdef MPF v cdef MPF w @@ -745,6 +744,9 @@ cdef class Context: faster and produces more accurate results than the builtin Python function :func:`sum`. + With squared=True each term is squared, and with absolute=True + the absolute value of each term is used. + TESTS :: sage: from mpmath import mp, fsum @@ -752,8 +754,13 @@ cdef class Context: sage: fsum([1, 2, 0.5, 7]) mpf('10.5') - With squared=True each term is squared, and with absolute=True - the absolute value of each term is used. + Check that the regression from `mpmath/issues/723 `__ + has been fixed:: + + sage: from mpmath import * + sage: mp.dps=16 + sage: zeta(-0.01 + 1000j) + mpc(real='-8.9714595...', imag='8.7321793...') """ cdef MPF sre, sim, tre, tim, tmp cdef mpf rr @@ -764,8 +771,8 @@ cdef class Context: workopts.prec = workopts.prec * 2 + 50 workopts.rounding = ROUND_D unknown = global_context.zero - sig_on() - try: # Way down, there is a ``finally`` with sig_off() + try: + sig_check() MPF_init(&sre) MPF_init(&sim) MPF_init(&tre) @@ -848,8 +855,8 @@ cdef class Context: MPF_clear(&sre) MPF_clear(&sim) return +unknown - finally: - sig_off() + except KeyboardInterrupt: + raise KeyboardInterrupt('Ctlr-C has been pressed') def fdot(ctx, A, B=None, bint conjugate=False): r""" From bd57c4d9d6eeeb8d79ade9c5e9546519309d5c6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Mon, 9 Oct 2023 11:19:24 +0200 Subject: [PATCH 093/216] a few more fixes --- src/sage/interfaces/gap3.py | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/src/sage/interfaces/gap3.py b/src/sage/interfaces/gap3.py index 602cf525481..d403dc8b9dc 100644 --- a/src/sage/interfaces/gap3.py +++ b/src/sage/interfaces/gap3.py @@ -178,7 +178,7 @@ sage: # optional - gap3 sage: gap3.load_package("chevie") - sage: gap3.version() # random + sage: gap3.version() # random # not tested 'lib: v3r4p4 1997/04/18, src: v3r4p0 1994/07/10, sys: usg gcc ansi' Working with GAP3 lists. Note that GAP3 lists are 1-indexed:: @@ -302,11 +302,12 @@ def __init__(self, command=gap3_cmd): EXAMPLES:: - sage: gap3 = Gap3() #optional - gap3 + sage: # optional - gap3 + sage: gap3 = Gap3() sage: gap3.is_running() False - sage: gap3._start() #optional - gap3 - sage: gap3.is_running() #optional - gap3 + sage: gap3._start() + sage: gap3.is_running() True """ self.__gap3_command_string = command @@ -341,18 +342,20 @@ def _start(self): EXAMPLES:: - sage: gap3 = Gap3() #optional - gap3 + sage: # optional - gap3 + sage: gap3 = Gap3() sage: gap3.is_running() False - sage: gap3._start() #optional - gap3 - sage: gap3.is_running() #optional - gap3 + sage: gap3._start() + sage: gap3.is_running() True Check that :trac:`23142` is fixed:: - sage: gap3.eval("1+1") #optional - gap3 + sage: # optional - gap3 + sage: gap3.eval("1+1") '2' - sage: gap3.quit() #optional - gap3 + sage: gap3.quit() """ Expect._start(self) # The -p command-line option to GAP3 produces the following @@ -504,7 +507,7 @@ def help(self, topic, pager=True): E.expect_list(self._compiled_small_pattern) # merge the help text into one string and print it. - helptext = "".join(helptext).strip() + helptext = "".join(bytes_to_str(line) for line in helptext).strip() if pager is True: from sage.misc.pager import pager as pag pag()(helptext) @@ -513,8 +516,9 @@ def help(self, topic, pager=True): def cputime(self, t=None): r""" - Returns the amount of CPU time that the GAP session has used in - seconds. If ``t`` is not None, then it returns the difference + Return the amount of CPU time that the GAP session has used in seconds. + + If ``t`` is not None, then it returns the difference between the current CPU time and ``t``. EXAMPLES:: From 58e2d0dfdb9647cc4bb2400e037ff8134e12d71d Mon Sep 17 00:00:00 2001 From: Dima Pasechnik Date: Wed, 4 Oct 2023 20:45:47 +0100 Subject: [PATCH 094/216] bump cysignals to 1.11.3 --- build/pkgs/cysignals/checksums.ini | 6 +++--- build/pkgs/cysignals/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/cysignals/checksums.ini b/build/pkgs/cysignals/checksums.ini index f374b70697c..890b112d9eb 100644 --- a/build/pkgs/cysignals/checksums.ini +++ b/build/pkgs/cysignals/checksums.ini @@ -1,5 +1,5 @@ tarball=cysignals-VERSION.tar.gz -sha1=7d42fa85f48123a988f43e437b01d13e42aba919 -md5=424a762509abdd80a7b55d302b83aa6e -cksum=1506931565 +sha1=f73968638bcae76bd68e63d241f7030fd4e2b0f3 +md5=3a499961b04c75928f3dd118f0374bdb +cksum=2887671070 upstream_url=https://pypi.io/packages/source/c/cysignals/cysignals-VERSION.tar.gz diff --git a/build/pkgs/cysignals/package-version.txt b/build/pkgs/cysignals/package-version.txt index ca7176690dd..0a5af26df3f 100644 --- a/build/pkgs/cysignals/package-version.txt +++ b/build/pkgs/cysignals/package-version.txt @@ -1 +1 @@ -1.11.2 +1.11.3 From b5dd6731b55a3d4052c316dbbb97aa5e70c15757 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 4 Oct 2023 15:05:07 -0700 Subject: [PATCH 095/216] build/pkgs/cysignals/patches: Remove --- .../patches/cython3-fix-warning.patch | 13 -------- .../cysignals/patches/cython3-legacy.patch | 30 ------------------- 2 files changed, 43 deletions(-) delete mode 100644 build/pkgs/cysignals/patches/cython3-fix-warning.patch delete mode 100644 build/pkgs/cysignals/patches/cython3-legacy.patch diff --git a/build/pkgs/cysignals/patches/cython3-fix-warning.patch b/build/pkgs/cysignals/patches/cython3-fix-warning.patch deleted file mode 100644 index 98cad9625e4..00000000000 --- a/build/pkgs/cysignals/patches/cython3-fix-warning.patch +++ /dev/null @@ -1,13 +0,0 @@ -diff --git a/src/cysignals/signals.pxd.in b/src/cysignals/signals.pxd.in -index c86e085..a98c8d1 100644 ---- a/src/cysignals/signals.pxd.in -+++ b/src/cysignals/signals.pxd.in -@@ -54,7 +54,7 @@ cdef extern from "macros.h" nogil: - # can be used to make Cython check whether there is a pending exception - # (PyErr_Occurred() is non-NULL). To Cython, it will look like - # cython_check_exception() actually raised the exception. --cdef inline void cython_check_exception() nogil except *: -+cdef inline void cython_check_exception() except * nogil: - pass - - diff --git a/build/pkgs/cysignals/patches/cython3-legacy.patch b/build/pkgs/cysignals/patches/cython3-legacy.patch deleted file mode 100644 index 274575d5d35..00000000000 --- a/build/pkgs/cysignals/patches/cython3-legacy.patch +++ /dev/null @@ -1,30 +0,0 @@ -commit 9996a4028ddc7f9a5ffda3df65d5b7d3b7df8aa5 -Author: Gonzalo Tornaría -Date: Wed Jul 19 18:34:57 2023 -0300 - - cython3 support using legacy directives - -diff --git a/setup.py b/setup.py -index 37acdfc..f68270b 100755 ---- a/setup.py -+++ b/setup.py -@@ -157,13 +157,17 @@ class build_ext(_build_ext): - # Run Cython with -Werror on continuous integration services - # with Python 3.6 or later - from Cython.Compiler import Options -- Options.warning_errors = True -+ Options.warning_errors = False - - from Cython.Build.Dependencies import cythonize - return cythonize(extensions, - build_dir=cythonize_dir, - include_path=["src", os.path.join(cythonize_dir, "src")], -- compiler_directives=dict(binding=True, language_level=2)) -+ compiler_directives=dict( -+ binding=True, -+ language_level=2, -+ legacy_implicit_noexcept=True, -+ )) - - - class build_py(_build_py): From 73d79e4973a07885ea914f8c05e7e9eb10712c6c Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 7 Oct 2023 13:20:07 -0700 Subject: [PATCH 096/216] build/pkgs/cysignals: Update to 1.11.4 --- build/pkgs/cysignals/checksums.ini | 6 +++--- build/pkgs/cysignals/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/cysignals/checksums.ini b/build/pkgs/cysignals/checksums.ini index 890b112d9eb..5c925fcc9ec 100644 --- a/build/pkgs/cysignals/checksums.ini +++ b/build/pkgs/cysignals/checksums.ini @@ -1,5 +1,5 @@ tarball=cysignals-VERSION.tar.gz -sha1=f73968638bcae76bd68e63d241f7030fd4e2b0f3 -md5=3a499961b04c75928f3dd118f0374bdb -cksum=2887671070 +sha1=76db7aa59d55e867c83b329c017382555253af43 +md5=1837370e1d7f0b0acf1b97c3b7323b7d +cksum=4114189395 upstream_url=https://pypi.io/packages/source/c/cysignals/cysignals-VERSION.tar.gz diff --git a/build/pkgs/cysignals/package-version.txt b/build/pkgs/cysignals/package-version.txt index 0a5af26df3f..3d0e62313ce 100644 --- a/build/pkgs/cysignals/package-version.txt +++ b/build/pkgs/cysignals/package-version.txt @@ -1 +1 @@ -1.11.3 +1.11.4 From 86cc7413ad9a4492cd1d2ee49f61b20cb5fbe850 Mon Sep 17 00:00:00 2001 From: Dima Pasechnik Date: Mon, 9 Oct 2023 10:04:59 +0100 Subject: [PATCH 097/216] add quotes, improve error message --- src/sage/libs/mpmath/ext_main.pyx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/libs/mpmath/ext_main.pyx b/src/sage/libs/mpmath/ext_main.pyx index ee8e37bd51c..a46c85ba52f 100644 --- a/src/sage/libs/mpmath/ext_main.pyx +++ b/src/sage/libs/mpmath/ext_main.pyx @@ -744,7 +744,7 @@ cdef class Context: faster and produces more accurate results than the builtin Python function :func:`sum`. - With squared=True each term is squared, and with absolute=True + With ``squared=True`` each term is squared, and with ``absolute=True`` the absolute value of each term is used. TESTS :: @@ -856,7 +856,7 @@ cdef class Context: MPF_clear(&sim) return +unknown except KeyboardInterrupt: - raise KeyboardInterrupt('Ctlr-C has been pressed') + raise KeyboardInterrupt('Ctrl-C pressed while running fsum') def fdot(ctx, A, B=None, bint conjugate=False): r""" From c5870dec674e210f5010fc41a1ea922f87203673 Mon Sep 17 00:00:00 2001 From: DavidAyotte Date: Mon, 9 Oct 2023 09:40:44 -0400 Subject: [PATCH 098/216] rename DrinfeldModule_complex into DrinfeldModule_charzero --- ..._drinfeld_module.py => charzero_drinfeld_module.py} | 10 +++++----- .../function_field/drinfeld_modules/drinfeld_module.py | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) rename src/sage/rings/function_field/drinfeld_modules/{complex_drinfeld_module.py => charzero_drinfeld_module.py} (97%) diff --git a/src/sage/rings/function_field/drinfeld_modules/complex_drinfeld_module.py b/src/sage/rings/function_field/drinfeld_modules/charzero_drinfeld_module.py similarity index 97% rename from src/sage/rings/function_field/drinfeld_modules/complex_drinfeld_module.py rename to src/sage/rings/function_field/drinfeld_modules/charzero_drinfeld_module.py index 8cb9e0d285f..d94dbe6e043 100644 --- a/src/sage/rings/function_field/drinfeld_modules/complex_drinfeld_module.py +++ b/src/sage/rings/function_field/drinfeld_modules/charzero_drinfeld_module.py @@ -3,7 +3,7 @@ Complex Drinfeld module This module provides the class -:class:`sage.rings.function_fields.drinfeld_module.complex_drinfeld_module.DrinfeldModule_complex`, +:class:`sage.rings.function_fields.drinfeld_module.complex_drinfeld_module.DrinfeldModule_charzero`, which inherits :class:`sage.rings.function_fields.drinfeld_module.drinfeld_module.DrinfeldModule`. @@ -31,7 +31,7 @@ lazy_import('sage.rings.lazy_series_ring', 'LazyPowerSeriesRing') -class DrinfeldModule_complex(DrinfeldModule): +class DrinfeldModule_charzero(DrinfeldModule): r""" This class implements complex Drinfeld `\mathbb{F}_q[T]`-modules. @@ -46,7 +46,7 @@ class DrinfeldModule_complex(DrinfeldModule): .. RUBRIC:: Construction: The user does not ever need to directly call - ``DrinfeldModule_complex`` --- the metaclass ``DrinfeldModule`` is + ``DrinfeldModule_charzero`` --- the metaclass ``DrinfeldModule`` is responsible for instantiating the right class depending on the input:: @@ -60,8 +60,8 @@ class DrinfeldModule_complex(DrinfeldModule): sage: isinstance(phi, DrinfeldModule) True - sage: from sage.rings.function_field.drinfeld_modules.complex_drinfeld_module import DrinfeldModule_complex - sage: isinstance(phi, DrinfeldModule_complex) + sage: from sage.rings.function_field.drinfeld_modules.complex_drinfeld_module import DrinfeldModule_charzero + sage: isinstance(phi, DrinfeldModule_charzero) True .. RUBRIC:: Logarithm and exponential diff --git a/src/sage/rings/function_field/drinfeld_modules/drinfeld_module.py b/src/sage/rings/function_field/drinfeld_modules/drinfeld_module.py index 58890f197f8..b0f177dfcfa 100644 --- a/src/sage/rings/function_field/drinfeld_modules/drinfeld_module.py +++ b/src/sage/rings/function_field/drinfeld_modules/drinfeld_module.py @@ -626,8 +626,8 @@ def __classcall_private__(cls, function_ring, gen, name='t'): from sage.rings.function_field.drinfeld_modules.finite_drinfeld_module import DrinfeldModule_finite return DrinfeldModule_finite(gen, category) if not category._characteristic: - from .complex_drinfeld_module import DrinfeldModule_complex - return DrinfeldModule_complex(gen, category) + from .charzero_drinfeld_module import DrinfeldModule_charzero + return DrinfeldModule_charzero(gen, category) return cls.__classcall__(cls, gen, category) def __init__(self, gen, category): From 7bcd4f6e916548442fd40aa1c00379eddf408fbb Mon Sep 17 00:00:00 2001 From: DavidAyotte Date: Mon, 9 Oct 2023 09:50:02 -0400 Subject: [PATCH 099/216] some documentation updates --- .../charzero_drinfeld_module.py | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/src/sage/rings/function_field/drinfeld_modules/charzero_drinfeld_module.py b/src/sage/rings/function_field/drinfeld_modules/charzero_drinfeld_module.py index d94dbe6e043..b69757af144 100644 --- a/src/sage/rings/function_field/drinfeld_modules/charzero_drinfeld_module.py +++ b/src/sage/rings/function_field/drinfeld_modules/charzero_drinfeld_module.py @@ -3,7 +3,7 @@ Complex Drinfeld module This module provides the class -:class:`sage.rings.function_fields.drinfeld_module.complex_drinfeld_module.DrinfeldModule_charzero`, +:class:`sage.rings.function_fields.drinfeld_module.charzero_drinfeld_module.DrinfeldModule_charzero`, which inherits :class:`sage.rings.function_fields.drinfeld_module.drinfeld_module.DrinfeldModule`. @@ -33,14 +33,12 @@ class DrinfeldModule_charzero(DrinfeldModule): r""" - This class implements complex Drinfeld `\mathbb{F}_q[T]`-modules. + This class implements Drinfeld `\mathbb{F}_q[T]`-modules defined + over fields of `\mathbb{F}_q[T]`-characteristic zero. - A *complex Drinfeld module* is a Drinfeld module whose base field - contains `\mathbb{F}_q(T)` and can be embedded in - `\mathbb{C}_{\infty}`, the completion of an algebraic closure of - `\mathbb{F}_q((1/T))` (the completion of `\mathbb{F}_q(T)`). - - For general definitions and help on Drinfeld modules, see class + Recall that the `\mathbb{F}_q[T]`-*characteristic* is defined as the + kernel of the underlying structure morphism. For general definitions + and help on Drinfeld modules, see class :class:`sage.rings.function_fields.drinfeld_module.drinfeld_module.DrinfeldModule`. .. RUBRIC:: Construction: @@ -60,14 +58,14 @@ class DrinfeldModule_charzero(DrinfeldModule): sage: isinstance(phi, DrinfeldModule) True - sage: from sage.rings.function_field.drinfeld_modules.complex_drinfeld_module import DrinfeldModule_charzero + sage: from sage.rings.function_field.drinfeld_modules.charzero_drinfeld_module import DrinfeldModule_charzero sage: isinstance(phi, DrinfeldModule_charzero) True .. RUBRIC:: Logarithm and exponential It is possible to calculate the logarithm and the exponential of - any complex Drinfeld modules:: + any Drinfeld modules of characteristic zero:: sage: A = GF(2)['T'] sage: K. = Frac(A) From c3ac0c7415019488cc34f949064009fc8f991fdf Mon Sep 17 00:00:00 2001 From: DavidAyotte Date: Mon, 9 Oct 2023 12:00:34 -0400 Subject: [PATCH 100/216] add goss polynomials documentation rubric --- .../drinfeld_modules/charzero_drinfeld_module.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/sage/rings/function_field/drinfeld_modules/charzero_drinfeld_module.py b/src/sage/rings/function_field/drinfeld_modules/charzero_drinfeld_module.py index b69757af144..08b3c6622a3 100644 --- a/src/sage/rings/function_field/drinfeld_modules/charzero_drinfeld_module.py +++ b/src/sage/rings/function_field/drinfeld_modules/charzero_drinfeld_module.py @@ -74,6 +74,22 @@ class DrinfeldModule_charzero(DrinfeldModule): z + ((1/(T^2+T))*z^2) + ((1/(T^8+T^6+T^5+T^3))*z^4) + O(z^8) sage: phi.logarithm() z + ((1/(T^2+T))*z^2) + ((1/(T^6+T^5+T^3+T^2))*z^4) + O(z^8) + + .. RUBRIC:: Goss polynomials + + Goss polynomials are a sequence of polynomials related with the + analytic theory of Drinfeld module. They provide a function field + analogue of certain classical trigonometric functions:: + + sage: A = GF(2)['T'] + sage: K. = Frac(A) + sage: phi = DrinfeldModule(A, [T, 1]) + sage: phi.goss_polynomial(1) + X + sage: phi.goss_polynomial(2) + X^2 + sage: phi.goss_polynomial(3) + X^3 + (1/(T^2 + T))*X^2 """ @cached_method def _compute_coefficient_exp(self, k): From 3332a899abd86dbe03b9c7834eb898cb5d4f86ff Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 9 Oct 2023 10:39:48 -0700 Subject: [PATCH 101/216] build/sage_bootstrap/download/mirror_list.py: Remove sagepad.org --- build/sage_bootstrap/download/mirror_list.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/build/sage_bootstrap/download/mirror_list.py b/build/sage_bootstrap/download/mirror_list.py index 12868bf6084..3a4b9d22fc5 100644 --- a/build/sage_bootstrap/download/mirror_list.py +++ b/build/sage_bootstrap/download/mirror_list.py @@ -200,8 +200,6 @@ def __iter__(self): pass for mirror in self.mirrors: yield mirror - # If all else fails: Try the packages we host ourselves - yield 'http://sagepad.org/' @property def fastest(self): From dd939ff74e271282a217ce5bcbeb8122672bdc0d Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 9 Oct 2023 12:25:44 -0700 Subject: [PATCH 102/216] sage_bootstrap.{tarball, download.mirror_list}: Lower layout of the mirror to mirror_list --- build/sage_bootstrap/download/mirror_list.py | 4 +++- build/sage_bootstrap/tarball.py | 5 ++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/build/sage_bootstrap/download/mirror_list.py b/build/sage_bootstrap/download/mirror_list.py index 3a4b9d22fc5..62f622b1392 100644 --- a/build/sage_bootstrap/download/mirror_list.py +++ b/build/sage_bootstrap/download/mirror_list.py @@ -199,7 +199,9 @@ def __iter__(self): except KeyError: pass for mirror in self.mirrors: - yield mirror + if not mirror.endswith('/'): + mirror += '/' + yield mirror + '/'.join(['spkg', 'upstream', '${SPKG}']) @property def fastest(self): diff --git a/build/sage_bootstrap/tarball.py b/build/sage_bootstrap/tarball.py index 18e3da97af8..e868c5fa51c 100644 --- a/build/sage_bootstrap/tarball.py +++ b/build/sage_bootstrap/tarball.py @@ -159,7 +159,10 @@ def download(self, allow_upstream=False): successful_download = False log.info('Attempting to download package {0} from mirrors'.format(self.filename)) for mirror in MirrorList(): - url = mirror + '/'.join(['spkg', 'upstream', self.package.name, self.filename]) + url = mirror.replace('${SPKG}', self.package.name) + if not url.endswith('/'): + url += '/' + url += self.filename log.info(url) try: Download(url, destination).run() From 2dfe081632fd4ba254cc6d3e34647f198151ab18 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 9 Oct 2023 12:28:18 -0700 Subject: [PATCH 103/216] sage_bootstrap.download.mirror_list: Delay downloading/reading/ranking to first use --- build/sage_bootstrap/download/mirror_list.py | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/build/sage_bootstrap/download/mirror_list.py b/build/sage_bootstrap/download/mirror_list.py index 62f622b1392..f03d03aabb4 100644 --- a/build/sage_bootstrap/download/mirror_list.py +++ b/build/sage_bootstrap/download/mirror_list.py @@ -51,7 +51,12 @@ class MirrorList(object): def __init__(self): self.filename = MIRRORLIST_FILENAME - self.mirrors = None + self._mirrors = None + + @property + def mirrors(self): + if self._mirrors is not None: + return self._mirrors try: self.mirrorfile = open(self.filename, 'r+t') @@ -67,8 +72,10 @@ def __init__(self): # process while we waited for the lock? Check again. if self._must_refresh(): self._refresh() - if self.mirrors is None: - self.mirrors = self._load() + if self._mirrors is None: + self._mirrors = self._load() + + return self._mirrors def _load(self, mirror_list=None): """ @@ -147,7 +154,7 @@ def _rank_mirrors(self): log.info('Cannot time mirrors via proxy, using default order') else: timed_mirrors.sort() - self.mirrors = [m[1] for m in timed_mirrors] + self._mirrors = [m[1] for m in timed_mirrors] log.info('Fastest mirror: ' + self.fastest) def _age(self): @@ -176,12 +183,12 @@ def _refresh(self): """ log.info('Downloading the Sage mirror list') try: - with contextlib.closing(urllib.urlopen(self.URL)) as f: + with contextlib.closing(urllib.urlopen(self.url)) as f: mirror_list = f.read().decode("ascii") except IOError: log.critical('Downloading the mirror list failed, using cached version') else: - self.mirrors = self._load(mirror_list) + self._mirrors = self._load(mirror_list) self._rank_mirrors() self._save() From a37f4fdd8261e1871f446593d62cb51903a5dae8 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 9 Oct 2023 12:32:03 -0700 Subject: [PATCH 104/216] sage_bootstrap.download.mirror_list: Use master list of download sources in SAGE_ROOT/.upstream.d --- .upstream.d/10-SAGE_SERVER | 2 + .../20-github.com-sagemath-sage-releases | 2 + .upstream.d/30-www.sagemath.org-mirror_list | 1 + build/sage_bootstrap/download/mirror_list.py | 56 +++++++++++++++++-- 4 files changed, 55 insertions(+), 6 deletions(-) create mode 100644 .upstream.d/10-SAGE_SERVER create mode 100644 .upstream.d/20-github.com-sagemath-sage-releases create mode 100644 .upstream.d/30-www.sagemath.org-mirror_list diff --git a/.upstream.d/10-SAGE_SERVER b/.upstream.d/10-SAGE_SERVER new file mode 100644 index 00000000000..40ee9e19450 --- /dev/null +++ b/.upstream.d/10-SAGE_SERVER @@ -0,0 +1,2 @@ +# When SAGE_SERVER is set, it should be an https/https server in the format of Sage mirrors. +${SAGE_SERVER}/spkg/upstream/${SPKG}/ diff --git a/.upstream.d/20-github.com-sagemath-sage-releases b/.upstream.d/20-github.com-sagemath-sage-releases new file mode 100644 index 00000000000..a9986bf3cce --- /dev/null +++ b/.upstream.d/20-github.com-sagemath-sage-releases @@ -0,0 +1,2 @@ +# Upstream packages as uploaded as GitHub release assets. +https://github.com/sagemath/sage/releases/download/10.1/ diff --git a/.upstream.d/30-www.sagemath.org-mirror_list b/.upstream.d/30-www.sagemath.org-mirror_list new file mode 100644 index 00000000000..951c1df6cfa --- /dev/null +++ b/.upstream.d/30-www.sagemath.org-mirror_list @@ -0,0 +1 @@ +https://www.sagemath.org/mirror_list diff --git a/build/sage_bootstrap/download/mirror_list.py b/build/sage_bootstrap/download/mirror_list.py index f03d03aabb4..f18c7b3e4b2 100644 --- a/build/sage_bootstrap/download/mirror_list.py +++ b/build/sage_bootstrap/download/mirror_list.py @@ -19,7 +19,7 @@ log = logging.getLogger() from sage_bootstrap.compat import urllib, urlparse -from sage_bootstrap.env import SAGE_DISTFILES +from sage_bootstrap.env import SAGE_DISTFILES, SAGE_ROOT from fcntl import flock, LOCK_SH, LOCK_EX from errno import ENOLCK @@ -41,16 +41,60 @@ class MirrorListException(RuntimeError): pass -MIRRORLIST_FILENAME = os.path.join(SAGE_DISTFILES, 'mirror_list') +class MirrorList(object): + def __init__(self): + self.sources = [] + upstream_d = os.path.join(SAGE_ROOT, '.upstream.d') + for fname in sorted(os.listdir(upstream_d)): + if '~' in fname or '#' in fname: + # Ignore auto-save and backup files + continue + try: + with open(os.path.join(upstream_d, fname), 'r') as f: + for line in f: + line = line.replace('${SAGE_ROOT}', SAGE_ROOT) + line = line.replace('${SAGE_DISTFILES}', SAGE_DISTFILES) + if '${SAGE_SERVER}' in line: + SAGE_SERVER = os.environ.get("SAGE_SERVER", "") + if not SAGE_SERVER: + continue + line = line.replace('${SAGE_SERVER}',) + line = line.strip() + if line.startswith('#'): + continue + if not line: + continue + if line.endswith('mirror_list'): + cache_filename = os.path.join(SAGE_DISTFILES, line.rpartition('/')[2]) + self.sources.append(MirrorList_from_url(line, cache_filename)) + else: + self.sources.append([line]) + except IOError: + # Silently ignore files that do not exist + pass -class MirrorList(object): + def __iter__(self): + """ + Iterate through the list of mirrors. + + This is the main entry point into the mirror list. Every + script should just use this function to try mirrors in order + of preference. This will not just yield the official mirrors, + but also urls for packages that are currently being tested. + """ + for source in self.sources: + for mirror in source: + yield mirror + + +class MirrorList_from_url(object): - URL = 'http://www.sagemath.org/mirror_list' MAXAGE = 24*60*60 # seconds - def __init__(self): - self.filename = MIRRORLIST_FILENAME + def __init__(self, url, filename): + self.url = url + self.filename = filename self._mirrors = None @property From 2323480b507a760d568727b11935949c52ed2d00 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 9 Oct 2023 13:09:38 -0700 Subject: [PATCH 105/216] src/bin/sage-update-version: Update .upstream.d/20-github.com-sagemath-sage-releases --- .../20-github.com-sagemath-sage-releases | 1 + src/bin/sage-update-version | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/.upstream.d/20-github.com-sagemath-sage-releases b/.upstream.d/20-github.com-sagemath-sage-releases index a9986bf3cce..6bccdd7ff0a 100644 --- a/.upstream.d/20-github.com-sagemath-sage-releases +++ b/.upstream.d/20-github.com-sagemath-sage-releases @@ -1,2 +1,3 @@ # Upstream packages as uploaded as GitHub release assets. +# This file is automatically updated by the sage-update-version script. https://github.com/sagemath/sage/releases/download/10.1/ diff --git a/src/bin/sage-update-version b/src/bin/sage-update-version index 29d8c794375..5ace38182ba 100755 --- a/src/bin/sage-update-version +++ b/src/bin/sage-update-version @@ -87,6 +87,25 @@ EOF # Create a top-level VERSION.txt file, which some external utilities rely on echo "$SAGE_VERSION_BANNER" > "$SAGE_ROOT/VERSION.txt" +# Add version to the front of GitHub release assets URLs. +SAGE_MINOR_VERSION=${SAGE_VERSION//.alpha*/} +SAGE_MINOR_VERSION=${SAGE_MINOR_VERSION//.beta*/} +SAGE_MINOR_VERSION=${SAGE_MINOR_VERSION//.dev*/} +SAGE_MINOR_VERSION=${SAGE_MINOR_VERSION//.post*/} +SAGE_MINOR_VERSION=${SAGE_MINOR_VERSION//.rc*/} +( echo "https://github.com/sagemath/sage/releases/download/$SAGE_MINOR_VERSION/" + sed '/^#/d' "$SAGE_ROOT/.upstream.d/20-github.com-sagemath-sage-releases" +) | uniq | head -n 3 > "$SAGE_ROOT/.upstream.d/20-github.com-sagemath-sage-releases.tmp" +( cat < "$SAGE_ROOT/.upstream.d/20-github.com-sagemath-sage-releases" +rm -f "$SAGE_ROOT/.upstream.d/20-github.com-sagemath-sage-releases.tmp" + +exit + # Regenerate auto-generated files tarball "$SAGE_ROOT/bootstrap" -s From dc71bd03c4db0e50cf85b8b3d1cdd4c44b9bd385 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gonzalo=20Tornar=C3=ADa?= Date: Mon, 2 Oct 2023 13:20:32 -0300 Subject: [PATCH 106/216] py312: changes in PyLong internals The layout for python integers changed in python 3.12. We add a module `sage.cpython.pycore_long` which copies the new (internal) api of PyLong from python 3.12. We also implement fallback version of these functions suitable for python pre-3.12. Note the files implementing the `pycore_long` module (`pycore_long.pxd` and `pycore_long.h`) are shared with fpylll and cypari2. --- src/sage/arith/long.pxd | 9 ++- src/sage/cpython/pycore_long.h | 98 +++++++++++++++++++++++++++++ src/sage/cpython/pycore_long.pxd | 9 +++ src/sage/libs/gmp/pylong.pxd | 3 +- src/sage/libs/gmp/pylong.pyx | 22 +++---- src/sage/symbolic/ginac/numeric.cpp | 13 ++-- 6 files changed, 129 insertions(+), 25 deletions(-) create mode 100644 src/sage/cpython/pycore_long.h create mode 100644 src/sage/cpython/pycore_long.pxd diff --git a/src/sage/arith/long.pxd b/src/sage/arith/long.pxd index 0031a0ae337..3ea70cef571 100644 --- a/src/sage/arith/long.pxd +++ b/src/sage/arith/long.pxd @@ -19,6 +19,8 @@ from libc.limits cimport LONG_MIN, LONG_MAX from cpython.object cimport Py_SIZE from cpython.number cimport PyNumber_Index, PyIndex_Check from cpython.longintrepr cimport py_long, PyLong_SHIFT, digit +from sage.cpython.pycore_long cimport ( + ob_digit, _PyLong_IsNegative, _PyLong_DigitCount) from sage.libs.gmp.mpz cimport mpz_fits_slong_p, mpz_get_si from sage.rings.integer_fake cimport is_Integer, Integer_AS_MPZ @@ -299,8 +301,11 @@ cdef inline bint integer_check_long_py(x, long* value, int* err): return 0 # x is a Python "int" (aka PyLongObject or py_long in cython) - cdef const digit* D = (x).ob_digit - cdef Py_ssize_t size = Py_SIZE(x) + cdef const digit* D = ob_digit(x) + cdef Py_ssize_t size = _PyLong_DigitCount(x) + + if _PyLong_IsNegative(x): + size = -size # We assume PyLong_SHIFT <= BITS_IN_LONG <= 3 * PyLong_SHIFT. # This is true in all the default configurations: diff --git a/src/sage/cpython/pycore_long.h b/src/sage/cpython/pycore_long.h new file mode 100644 index 00000000000..ff1a73d097a --- /dev/null +++ b/src/sage/cpython/pycore_long.h @@ -0,0 +1,98 @@ +#include "Python.h" +#include + +#if PY_VERSION_HEX >= 0x030C00A5 +#define ob_digit(o) (((PyLongObject*)o)->long_value.ob_digit) +#else +#define ob_digit(o) (((PyLongObject*)o)->ob_digit) +#endif + +#if PY_VERSION_HEX >= 0x030C00A7 +// taken from cpython:Include/internal/pycore_long.h @ 3.12 + +/* Long value tag bits: + * 0-1: Sign bits value = (1-sign), ie. negative=2, positive=0, zero=1. + * 2: Reserved for immortality bit + * 3+ Unsigned digit count + */ +#define SIGN_MASK 3 +#define SIGN_ZERO 1 +#define SIGN_NEGATIVE 2 +#define NON_SIZE_BITS 3 + +static inline bool +_PyLong_IsZero(const PyLongObject *op) +{ + return (op->long_value.lv_tag & SIGN_MASK) == SIGN_ZERO; +} + +static inline bool +_PyLong_IsNegative(const PyLongObject *op) +{ + return (op->long_value.lv_tag & SIGN_MASK) == SIGN_NEGATIVE; +} + +static inline bool +_PyLong_IsPositive(const PyLongObject *op) +{ + return (op->long_value.lv_tag & SIGN_MASK) == 0; +} + +static inline Py_ssize_t +_PyLong_DigitCount(const PyLongObject *op) +{ + assert(PyLong_Check(op)); + return op->long_value.lv_tag >> NON_SIZE_BITS; +} + +#define TAG_FROM_SIGN_AND_SIZE(sign, size) ((1 - (sign)) | ((size) << NON_SIZE_BITS)) + +static inline void +_PyLong_SetSignAndDigitCount(PyLongObject *op, int sign, Py_ssize_t size) +{ + assert(size >= 0); + assert(-1 <= sign && sign <= 1); + assert(sign != 0 || size == 0); + op->long_value.lv_tag = TAG_FROM_SIGN_AND_SIZE(sign, (size_t)size); +} + +#else +// fallback for < 3.12 + +static inline bool +_PyLong_IsZero(const PyLongObject *op) +{ + return Py_SIZE(op) == 0; +} + +static inline bool +_PyLong_IsNegative(const PyLongObject *op) +{ + return Py_SIZE(op) < 0; +} + +static inline bool +_PyLong_IsPositive(const PyLongObject *op) +{ + return Py_SIZE(op) > 0; +} + +static inline Py_ssize_t +_PyLong_DigitCount(const PyLongObject *op) +{ + Py_ssize_t size = Py_SIZE(op); + return size < 0 ? -size : size; +} + +static inline void +_PyLong_SetSignAndDigitCount(PyLongObject *op, int sign, Py_ssize_t size) +{ +#if (PY_MAJOR_VERSION == 3) && (PY_MINOR_VERSION < 9) +// The function Py_SET_SIZE is defined starting with python 3.9. + Py_SIZE(o) = size; +#else + Py_SET_SIZE(op, sign < 0 ? -size : size); +#endif +} + +#endif diff --git a/src/sage/cpython/pycore_long.pxd b/src/sage/cpython/pycore_long.pxd new file mode 100644 index 00000000000..41de637ff18 --- /dev/null +++ b/src/sage/cpython/pycore_long.pxd @@ -0,0 +1,9 @@ +from cpython.longintrepr cimport py_long, digit + +cdef extern from "pycore_long.h": + digit* ob_digit(py_long o) + bint _PyLong_IsZero(py_long o) + bint _PyLong_IsNegative(py_long o) + bint _PyLong_IsPositive(py_long o) + Py_ssize_t _PyLong_DigitCount(py_long o) + void _PyLong_SetSignAndDigitCount(py_long o, int sign, Py_ssize_t size) diff --git a/src/sage/libs/gmp/pylong.pxd b/src/sage/libs/gmp/pylong.pxd index a73f1da6d6f..84e1bb8cd87 100644 --- a/src/sage/libs/gmp/pylong.pxd +++ b/src/sage/libs/gmp/pylong.pxd @@ -2,9 +2,10 @@ Various functions to deal with conversion mpz <-> Python int/long """ +from cpython.longintrepr cimport py_long from sage.libs.gmp.types cimport * cdef mpz_get_pylong(mpz_srcptr z) cdef mpz_get_pyintlong(mpz_srcptr z) -cdef int mpz_set_pylong(mpz_ptr z, L) except -1 +cdef int mpz_set_pylong(mpz_ptr z, py_long L) except -1 cdef Py_hash_t mpz_pythonhash(mpz_srcptr z) diff --git a/src/sage/libs/gmp/pylong.pyx b/src/sage/libs/gmp/pylong.pyx index d5993cca5a5..1a36c29d3fa 100644 --- a/src/sage/libs/gmp/pylong.pyx +++ b/src/sage/libs/gmp/pylong.pyx @@ -28,6 +28,8 @@ AUTHORS: from cpython.object cimport Py_SIZE from cpython.long cimport PyLong_FromLong from cpython.longintrepr cimport _PyLong_New, py_long, digit, PyLong_SHIFT +from sage.cpython.pycore_long cimport (ob_digit, _PyLong_IsNegative, + _PyLong_DigitCount, _PyLong_SetSignAndDigitCount) from .mpz cimport * cdef extern from *: @@ -60,12 +62,9 @@ cdef mpz_get_pylong_large(mpz_srcptr z): """ cdef size_t nbits = mpz_sizeinbase(z, 2) cdef size_t pylong_size = (nbits + PyLong_SHIFT - 1) // PyLong_SHIFT - L = _PyLong_New(pylong_size) - mpz_export(L.ob_digit, NULL, - -1, sizeof(digit), 0, PyLong_nails, z) - if mpz_sgn(z) < 0: - # Set correct size - Py_SET_SIZE(L, -pylong_size) + cdef py_long L = _PyLong_New(pylong_size) + mpz_export(ob_digit(L), NULL, -1, sizeof(digit), 0, PyLong_nails, z) + _PyLong_SetSignAndDigitCount(L, mpz_sgn(z), pylong_size) return L @@ -88,16 +87,13 @@ cdef mpz_get_pyintlong(mpz_srcptr z): return mpz_get_pylong_large(z) -cdef int mpz_set_pylong(mpz_ptr z, L) except -1: +cdef int mpz_set_pylong(mpz_ptr z, py_long L) except -1: """ Convert a Python ``long`` `L` to an ``mpz``. """ - cdef Py_ssize_t pylong_size = Py_SIZE(L) - if pylong_size < 0: - pylong_size = -pylong_size - mpz_import(z, pylong_size, -1, sizeof(digit), 0, PyLong_nails, - (L).ob_digit) - if Py_SIZE(L) < 0: + cdef Py_ssize_t pylong_size = _PyLong_DigitCount(L) + mpz_import(z, pylong_size, -1, sizeof(digit), 0, PyLong_nails, ob_digit(L)) + if _PyLong_IsNegative(L): mpz_neg(z, z) diff --git a/src/sage/symbolic/ginac/numeric.cpp b/src/sage/symbolic/ginac/numeric.cpp index c4152e092e3..4bcf45e8793 100644 --- a/src/sage/symbolic/ginac/numeric.cpp +++ b/src/sage/symbolic/ginac/numeric.cpp @@ -67,6 +67,7 @@ #include "archive.h" #include "tostring.h" #include "utils.h" +#include "../../cpython/pycore_long.h" #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-register" @@ -706,18 +707,12 @@ static long _mpq_pythonhash(mpq_t the_rat) // Initialize an mpz_t from a Python long integer static void _mpz_set_pylong(mpz_t z, PyLongObject* l) { - Py_ssize_t pylong_size = Py_SIZE(l); - int sign = 1; - - if (pylong_size < 0) { - pylong_size = -pylong_size; - sign = -1; - } + Py_ssize_t pylong_size = _PyLong_DigitCount(l); mpz_import(z, pylong_size, -1, sizeof(digit), 0, - 8*sizeof(digit) - PyLong_SHIFT, l->ob_digit); + 8*sizeof(digit) - PyLong_SHIFT, ob_digit(l)); - if (sign < 0) + if (_PyLong_IsNegative(l)) mpz_neg(z, z); } From 4d35af2b4d971292851a042ebc61b6213f38299e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gonzalo=20Tornar=C3=ADa?= Date: Mon, 2 Oct 2023 21:20:31 -0300 Subject: [PATCH 107/216] py312: atexit_callback change In python 3.12, the `struct atexit_callback` was renamed to `struct atexit_py_callback`. The easiest workaround is to add `#define atexit_callback atexit_py_callback` in the right place when building using python 3.12 or newer. --- src/sage/cpython/atexit.pyx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/sage/cpython/atexit.pyx b/src/sage/cpython/atexit.pyx index 961aa348d0a..e5a82735137 100644 --- a/src/sage/cpython/atexit.pyx +++ b/src/sage/cpython/atexit.pyx @@ -154,6 +154,10 @@ cdef extern from *: #undef _PyGC_FINALIZED #include "internal/pycore_interp.h" #include "internal/pycore_pystate.h" + #if PY_VERSION_HEX >= 0x030c0000 + // struct atexit_callback was renamed in 3.12 to atexit_py_callback + #define atexit_callback atexit_py_callback + #endif static atexit_callback ** _atexit_callbacks(PyObject *self) { PyInterpreterState *interp = _PyInterpreterState_GET(); struct atexit_state state = interp->atexit; From 2f31aa859899d51cc80aabed2533793d1ff07dd5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gonzalo=20Tornar=C3=ADa?= Date: Mon, 2 Oct 2023 21:21:15 -0300 Subject: [PATCH 108/216] py312: disable cython profile=true in one file Tracing has changed in python 3.12 in such a way that cython doesn't support it properly anymore. This one file sets `profile=true` for cython which won't work anymore (and it fails to build, at least with cython 0.29). We just disable that line. See also: https://github.com/cython/cython/issues/5450 --- src/sage/matroids/lean_matrix.pyx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/sage/matroids/lean_matrix.pyx b/src/sage/matroids/lean_matrix.pyx index 54c68e637c0..a137cbf70e5 100644 --- a/src/sage/matroids/lean_matrix.pyx +++ b/src/sage/matroids/lean_matrix.pyx @@ -1,5 +1,4 @@ # sage.doctest: optional - sage.rings.finite_rings -# cython: profile=True """ Lean matrices From c9c50269912971ba4f38662a221bd22ca124b0da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gonzalo=20Tornar=C3=ADa?= Date: Mon, 2 Oct 2023 21:22:13 -0300 Subject: [PATCH 109/216] py312: fix issue when including internal python header To use some (internal) declarations related to dict type, we have to include `` which needs `#define Py_BUILD_CORE` to be loaded. This causes trouble when `Python.h` was included before defining `Py_BUILD_CORE`, due to a macro `_PyGC_FINALIZED`. We fix it by undefining said macro. --- src/sage/cpython/dict_internal.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/sage/cpython/dict_internal.h b/src/sage/cpython/dict_internal.h index 42a57bcb468..a5ee35bc198 100644 --- a/src/sage/cpython/dict_internal.h +++ b/src/sage/cpython/dict_internal.h @@ -169,6 +169,7 @@ dictkeys_set_index(PyDictKeysObject *keys, Py_ssize_t i, Py_ssize_t ix) #else /* Python >= 3.11 */ #define Py_BUILD_CORE +#undef _PyGC_FINALIZED #include /************************************************************/ From ca63dcf2e3c06274e83beb79ebc9fb1ea9f96883 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gonzalo=20Tornar=C3=ADa?= Date: Mon, 2 Oct 2023 22:57:18 -0300 Subject: [PATCH 110/216] py312: use new api for ast Some changes in ast, the old `node.n` and `node.s` are deprecated in favour of a common `node.value`. Making this change seems better than just ignoring the deprecation warning. --- src/sage/misc/sageinspect.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/misc/sageinspect.py b/src/sage/misc/sageinspect.py index f0545be7d81..811afc48755 100644 --- a/src/sage/misc/sageinspect.py +++ b/src/sage/misc/sageinspect.py @@ -602,7 +602,7 @@ def visit_Num(self, node): On Python 3 negative numbers are parsed first, for some reason, as a UnaryOp node. """ - return node.n + return node.value def visit_Str(self, node): r""" @@ -624,7 +624,7 @@ def visit_Str(self, node): sage: [vis(s) for s in ['"abstract"', "'syntax'", r'''r"tr\ee"''']] ['abstract', 'syntax', 'tr\\ee'] """ - return node.s + return node.value def visit_List(self, node): """ From 7710fc0b8aa5f697dca2d655e097144f41382d42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gonzalo=20Tornar=C3=ADa?= Date: Mon, 2 Oct 2023 22:57:55 -0300 Subject: [PATCH 111/216] py312: filter deprecation warnings This adds some filterwarnings that trigger with python 3.12. - deprecation of `datetime.datetime.utcfromtimestamp()` this is triggered by python modules `dateutil` and `sphinx`. - `os.fork()` and `os.ptyfork()` are deprecated when running multi-threaded; I don't see an easy way out of this, so ignore it. - itertools won't support pickling in python 3.14; let's ignore this for now with the hope there's an alternative before 3.14. --- src/sage/all__sagemath_repl.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/sage/all__sagemath_repl.py b/src/sage/all__sagemath_repl.py index 8d0b43679ca..c31b206bcb8 100644 --- a/src/sage/all__sagemath_repl.py +++ b/src/sage/all__sagemath_repl.py @@ -79,6 +79,23 @@ message=r"Use setlocale\(\), getencoding\(\) and getlocale\(\) instead", module='docutils.io') +# triggered by dateutil 2.8.2 and sphinx 7.0.1 on Python 3.12 +# see: https://github.com/dateutil/dateutil/pull/1285 +# see: https://github.com/sphinx-doc/sphinx/pull/11468 +warnings.filterwarnings('ignore', category=DeprecationWarning, + message=r"datetime.datetime.utcfromtimestamp\(\) is deprecated", + module='dateutil.tz.tz|sphinx.(builders.gettext|util.i18n)') + +# triggered on Python 3.12 +warnings.filterwarnings('ignore', category=DeprecationWarning, + message=r"This process.* is multi-threaded, " + r"use of .*\(\) may lead to deadlocks in the child.") + +# pickling of itertools is deprecated in Python 3.12 +warnings.filterwarnings('ignore', category=DeprecationWarning, + message=r"Pickle, copy, and deepcopy support will be " + r"removed from itertools in Python 3.14.") + from .all__sagemath_objects import * from .all__sagemath_environment import * From 57a5468a0fe650750d23e8d707e4c4216c04c0cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gonzalo=20Tornar=C3=ADa?= Date: Mon, 2 Oct 2023 23:14:51 -0300 Subject: [PATCH 112/216] py312: don't use `pkgutil.find_loader()` Is deprecated, and it can be replaced just fine with `importlib.util.find_spec()`. --- src/sage/sat/solvers/satsolver.pyx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sage/sat/solvers/satsolver.pyx b/src/sage/sat/solvers/satsolver.pyx index c2f41b18f55..1c4ac400cb6 100644 --- a/src/sage/sat/solvers/satsolver.pyx +++ b/src/sage/sat/solvers/satsolver.pyx @@ -375,10 +375,10 @@ def SAT(solver=None, *args, **kwds): DIMACS Solver: 'kissat -q {input}' """ if solver is None: - import pkgutil - if pkgutil.find_loader('pycryptosat') is not None: + from importlib.util import find_spec + if find_spec('pycryptosat') is not None: solver = "cryptominisat" - elif pkgutil.find_loader('pycosat') is not None: + elif find_spec('pycosat') is not None: solver = "picosat" else: solver = "LP" From 29e4ebddf7631704b3c419912e2a0d7fb983c859 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gonzalo=20Tornar=C3=ADa?= Date: Wed, 4 Oct 2023 10:43:44 -0300 Subject: [PATCH 113/216] py312: fix `sage.misc.dev_tools.load_submodules()` Since `importer.find_module(...)` was removed in 3.12. We just follow the suggestion from https://docs.python.org/3/library/importlib.html#importing-a-source-file-directly Note that the last three added lines here could be replaced instead by spec.loader.load_module(module_name) which works; however this is deprecated so it's better to use the recommended way using `importlib.util.module_from_spec(...)` and `spec.loader.execute_module(...)`. --- src/sage/misc/dev_tools.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/sage/misc/dev_tools.py b/src/sage/misc/dev_tools.py index e7bf176592c..3ece7db2894 100644 --- a/src/sage/misc/dev_tools.py +++ b/src/sage/misc/dev_tools.py @@ -171,6 +171,7 @@ def load_submodules(module=None, exclude_pattern=None): load sage.geometry.polyhedron.ppl_lattice_polygon... succeeded """ from .package_dir import walk_packages + import importlib.util if module is None: import sage @@ -194,8 +195,12 @@ def load_submodules(module=None, exclude_pattern=None): try: sys.stdout.write("load %s..." % module_name) sys.stdout.flush() - loader = importer.find_module(module_name) - loader.load_module(module_name) + # see + # https://docs.python.org/3/library/importlib.html#importing-a-source-file-directly + spec = importer.find_spec(module_name) + module = importlib.util.module_from_spec(spec) + sys.modules[module_name] = module + spec.loader.exec_module(module) sys.stdout.write(" succeeded\n") except (ValueError, AttributeError, TypeError, ImportError): # we might get error because of cython code that has been From 07ee873163308b9d57a0fd85c665a9e3ecb0fd90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gonzalo=20Tornar=C3=ADa?= Date: Wed, 4 Oct 2023 13:08:43 -0300 Subject: [PATCH 114/216] py312: sum changed in python 3.12, fix doctest In python < 3.12 we have sage: a = delta_qexp(1000) sage: sum(a[n]/float(n)^14 for n in range(1,1000)) 0.9985830631627459 This changed in python 3.12 to sage: sum(a[n]/float(n)^14 for n in range(1,1000)) 0.9985830631627461 The latter is the correct one as can be seen using rationals: sage: float(sum(a[n]/n^14 for n in range(1,1000))) 0.9985830631627461 As a workaround, we do the sum in reverse (from small to large terms), which gives the correct result in any case: sage: sum(a[n]/float(n)^14 for n in reversed(range(1,1000))) 0.9985830631627461 --- src/sage/lfunctions/dokchitser.py | 4 ++-- src/sage/lfunctions/pari.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sage/lfunctions/dokchitser.py b/src/sage/lfunctions/dokchitser.py index 58499396d6c..16119d20815 100644 --- a/src/sage/lfunctions/dokchitser.py +++ b/src/sage/lfunctions/dokchitser.py @@ -418,8 +418,8 @@ def init_coeffs(self, v, cutoff=1, sage: L(14) 0.998583063162746 sage: a = delta_qexp(1000) - sage: sum(a[n]/float(n)^14 for n in range(1,1000)) - 0.9985830631627459 + sage: sum(a[n]/float(n)^14 for n in reversed(range(1,1000))) + 0.9985830631627461 Illustrate that one can give a list of complex numbers for v (see :trac:`10937`):: diff --git a/src/sage/lfunctions/pari.py b/src/sage/lfunctions/pari.py index bbf289aa21c..e4968866303 100644 --- a/src/sage/lfunctions/pari.py +++ b/src/sage/lfunctions/pari.py @@ -141,8 +141,8 @@ def init_coeffs(self, v, cutoff=None, w=1): sage: L(14) 0.998583063162746 sage: a = delta_qexp(1000) - sage: sum(a[n]/float(n)^14 for n in range(1,1000)) - 0.9985830631627459 + sage: sum(a[n]/float(n)^14 for n in reversed(range(1,1000))) + 0.9985830631627461 Illustrate that one can give a list of complex numbers for v (see :trac:`10937`):: From 3600123d07190f838cf1654573717a9b7670e651 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gonzalo=20Tornar=C3=ADa?= Date: Wed, 4 Oct 2023 22:05:38 -0300 Subject: [PATCH 115/216] py312: use dict instead of OrderedDict for consistent printing In python 3.12 the printing of OrderedDict has been changed. As of Python 3.7, regular dicts are guaranteed to be ordered, so it's safe to replace OrderedDict by dict. Maybe convenient to replace other uses of OrderedDict, although this is out of scope of python 3.12 support. --- src/sage/monoids/trace_monoid.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/sage/monoids/trace_monoid.py b/src/sage/monoids/trace_monoid.py index 00baa4d14f8..f8176a1e1f2 100644 --- a/src/sage/monoids/trace_monoid.py +++ b/src/sage/monoids/trace_monoid.py @@ -40,7 +40,6 @@ # https://www.gnu.org/licenses/ # **************************************************************************** -from collections import OrderedDict from itertools import repeat, chain, product from sage.misc.cachefunc import cached_method @@ -633,14 +632,14 @@ def _compute_dependence_stack(self, x): sage: x = b*a*d*a*c*b sage: M._compute_dependence_stack(x) ({a, b, c, d}, - OrderedDict([(a, [False, False, True, True, False]), - (b, [True, False, False, False, True]), - (c, [True, False, False, False]), - (d, [False, False, True, False])])) + {a: [False, False, True, True, False], + b: [True, False, False, False, True], + c: [True, False, False, False], + d: [False, False, True, False]}) """ independence = self._independence generators_set = set(e for e, _ in x) - stacks = OrderedDict(sorted((g, []) for g in generators_set)) + stacks = dict(sorted((g, []) for g in generators_set)) for generator, times in reversed(list(x)): stacks[generator].extend(repeat(True, times)) for other_gen in generators_set: From 168063c6ade00dcfa9666d4baf07ecc7e3af23d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gonzalo=20Tornar=C3=ADa?= Date: Wed, 4 Oct 2023 23:35:28 -0300 Subject: [PATCH 116/216] py312: fix crash in polyhedron face iterator Running sage: g = Polyhedron().face_generator() sage: g.__next__() A -1-dimensional face of a Polyhedron in ZZ^0 sage: g.__next__() is supposed to raise `StopIteration`. However in python 3.12 the second call to `__next__()` leads to a crash. This is caused by a `return -1` in `next_face_loop()` which is supposed to mean `raise StopIteration`. Using raise explicitly fixes the crash. --- .../polyhedron/combinatorial_polyhedron/face_iterator.pyx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/sage/geometry/polyhedron/combinatorial_polyhedron/face_iterator.pyx b/src/sage/geometry/polyhedron/combinatorial_polyhedron/face_iterator.pyx index 98782303012..f03f0f832ff 100644 --- a/src/sage/geometry/polyhedron/combinatorial_polyhedron/face_iterator.pyx +++ b/src/sage/geometry/polyhedron/combinatorial_polyhedron/face_iterator.pyx @@ -1945,7 +1945,8 @@ cdef inline int next_face_loop(iter_t structure) nogil except -1: # The function is not supposed to be called, # just prevent it from crashing. # Actually raising an error here results in a bad branch prediction. - return -1 + # But return -1 results in a crash with python 3.12 + raise StopIteration # Getting ``[faces, n_faces, n_visited_all]`` according to dimension. cdef face_list_t* faces = &structure.new_faces[structure.current_dimension] From 0a1dd3808034714a313cf70f7756ceceb5fcc9fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gonzalo=20Tornar=C3=ADa?= Date: Wed, 4 Oct 2023 23:42:55 -0300 Subject: [PATCH 117/216] py312: fix warning in string literal --- build/sage_bootstrap/package.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/sage_bootstrap/package.py b/build/sage_bootstrap/package.py index 15b342223c4..eb82f96e05f 100644 --- a/build/sage_bootstrap/package.py +++ b/build/sage_bootstrap/package.py @@ -303,7 +303,7 @@ def _init_checksum(self): # Name of the directory containing the checksums.ini file self.__tarball_package_name = os.path.realpath(checksums_ini).split(os.sep)[-2] - VERSION_PATCHLEVEL = re.compile('(?P.*)\.p(?P[0-9]+)') + VERSION_PATCHLEVEL = re.compile(r'(?P.*)\.p(?P[0-9]+)') def _init_version(self): try: From 3a7cd3f27245268991c0becf2e6e1c1568811674 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gonzalo=20Tornar=C3=ADa?= Date: Wed, 4 Oct 2023 23:50:31 -0300 Subject: [PATCH 118/216] py312: skip a test that fails with python 3.12 --- src/sage/cpython/debug.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/cpython/debug.pyx b/src/sage/cpython/debug.pyx index 022d8e1fed7..cdaca3a4854 100644 --- a/src/sage/cpython/debug.pyx +++ b/src/sage/cpython/debug.pyx @@ -78,7 +78,7 @@ def getattr_debug(obj, name, default=_no_default): EXAMPLES:: - sage: _ = getattr_debug(list, "reverse") + sage: _ = getattr_debug(list, "reverse") # not tested - broken in python 3.12 getattr_debug(obj=, name='reverse'): type(obj) = object has __dict__ slot () From 7e6526068c86068d840651c97593ddd445f38336 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 9 Oct 2023 14:53:41 -0700 Subject: [PATCH 119/216] sage_bootstrap.download.mirror_list: Skip empty lines earlier --- build/sage_bootstrap/download/mirror_list.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/build/sage_bootstrap/download/mirror_list.py b/build/sage_bootstrap/download/mirror_list.py index f18c7b3e4b2..a8baa66da2d 100644 --- a/build/sage_bootstrap/download/mirror_list.py +++ b/build/sage_bootstrap/download/mirror_list.py @@ -53,18 +53,18 @@ def __init__(self): try: with open(os.path.join(upstream_d, fname), 'r') as f: for line in f: + line = line.strip() + if line.startswith('#'): + continue + if not line: + continue line = line.replace('${SAGE_ROOT}', SAGE_ROOT) line = line.replace('${SAGE_DISTFILES}', SAGE_DISTFILES) if '${SAGE_SERVER}' in line: SAGE_SERVER = os.environ.get("SAGE_SERVER", "") if not SAGE_SERVER: continue - line = line.replace('${SAGE_SERVER}',) - line = line.strip() - if line.startswith('#'): - continue - if not line: - continue + line = line.replace('${SAGE_SERVER}', SAGE_SERVER) if line.endswith('mirror_list'): cache_filename = os.path.join(SAGE_DISTFILES, line.rpartition('/')[2]) self.sources.append(MirrorList_from_url(line, cache_filename)) From 371be50a9df9e2ed693a6c4fafaace67f9308e3b Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 9 Oct 2023 14:55:32 -0700 Subject: [PATCH 120/216] src/bin/sage-update-version: Also commit --- src/bin/sage-update-version | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/bin/sage-update-version b/src/bin/sage-update-version index 5ace38182ba..3b7358d2929 100755 --- a/src/bin/sage-update-version +++ b/src/bin/sage-update-version @@ -104,8 +104,6 @@ EOF ) > "$SAGE_ROOT/.upstream.d/20-github.com-sagemath-sage-releases" rm -f "$SAGE_ROOT/.upstream.d/20-github.com-sagemath-sage-releases.tmp" -exit - # Regenerate auto-generated files tarball "$SAGE_ROOT/bootstrap" -s @@ -125,6 +123,7 @@ git commit -m "Updated SageMath version to $SAGE_VERSION" -- \ "$SAGE_ROOT/build/pkgs/configure/package-version.txt" \ "$SAGE_ROOT/build/pkgs/*/install-requires.txt" \ "$SAGE_ROOT"/pkgs/*/VERSION.txt \ + "$SAGE_ROOT/.upstream.d/20-github.com-sagemath-sage-releases" \ || die "Error committing to the repository." git tag -a "$SAGE_VERSION" -m "$SAGE_VERSION_BANNER" \ From 423e48a3f54de03df73afe1d7fa33e8394af8d3a Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 9 Oct 2023 15:28:13 -0700 Subject: [PATCH 121/216] build/bin/write-dockerfile.sh: ADD .upstream.d --- build/bin/write-dockerfile.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/build/bin/write-dockerfile.sh b/build/bin/write-dockerfile.sh index 530c2c6ec63..5e5eb522de5 100755 --- a/build/bin/write-dockerfile.sh +++ b/build/bin/write-dockerfile.sh @@ -223,6 +223,7 @@ $ADD src/Pipfile.m4 src/pyproject.toml.m4 src/requirements.txt.m4 src/setup.cfg. $ADD m4 ./m4 $ADD pkgs pkgs $ADD build ./build +$ADD .upstream.d ./.upstream.d ARG BOOTSTRAP=./bootstrap $RUN sh -x -c "\${BOOTSTRAP}" $ENDRUN From 976352eaf097c0dc0c85195af07986ab27bb8d97 Mon Sep 17 00:00:00 2001 From: Michael Orlitzky Date: Mon, 9 Oct 2023 20:57:59 -0400 Subject: [PATCH 122/216] src/sage/misc/latex.py: replace tmp_dir() These bits of code only use one temporary file, but they call a function _run_latex_() that writes its output file to the same directory as its input file. Since we don't want the output path to be predictable (for security reasons), we have to "hide" the one temporary file inside of a temporary directory that will only be writable by the Sage user. In other words: standard tempfile.TemporaryDirecrory() replacement. Issue: https://github.com/sagemath/sage/issues/36322 --- src/sage/misc/latex.py | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/src/sage/misc/latex.py b/src/sage/misc/latex.py index 25b1ff557be..ca99e298a8d 100644 --- a/src/sage/misc/latex.py +++ b/src/sage/misc/latex.py @@ -30,9 +30,9 @@ import re import shutil from subprocess import call, PIPE +from tempfile import TemporaryDirectory from sage.misc.cachefunc import cached_function, cached_method -from sage.misc.temporary_file import tmp_dir from sage.structure.sage_object import SageObject from sage.misc.lazy_import import lazy_import @@ -1103,7 +1103,8 @@ def eval(self, x, globals, strip=False, filename=None, debug=None, filename = 'sage%s' % random.randint(1, 100) # to defeat browser caches else: filename = os.path.splitext(filename)[0] # get rid of extension - base = tmp_dir() + + base = TemporaryDirectory() orig_base, filename = os.path.split(os.path.abspath(filename)) if len(filename.split()) > 1: raise ValueError("filename must contain no spaces") @@ -1134,13 +1135,14 @@ def eval(self, x, globals, strip=False, filename=None, debug=None, engine = self.__engine e = _run_latex_(os.path.join(base, filename + ".tex"), debug=debug, density=density, engine=engine, png=True) + result = None if e.find("Error") == -1: shutil.copy(os.path.join(base, filename + ".png"), os.path.join(orig_base, filename + ".png")) - shutil.rmtree(base) - return '' - else: - return + result = '' + + base.cleanup() + return result def blackboard_bold(self, t=None): r"""nodetex @@ -1918,7 +1920,7 @@ def view(objects, title='Sage', debug=False, sep='', tiny=False, if pdflatex or (viewer == "pdf" and engine == "latex"): engine = "pdflatex" # command line or notebook with viewer - tmp = tmp_dir('sage_viewer') + tmp = TemporaryDirectory() tex_file = os.path.join(tmp, "sage.tex") with open(tex_file, 'w') as file: file.write(s) @@ -1931,6 +1933,7 @@ def view(objects, title='Sage', debug=False, sep='', tiny=False, viewer = dvi_viewer() else: print("Latex error") + tmp.cleanup() return output_file = os.path.join(tmp, "sage." + suffix) # this should get changed if we switch the stuff in misc.viewer to @@ -1939,6 +1942,8 @@ def view(objects, title='Sage', debug=False, sep='', tiny=False, print('viewer: "{}"'.format(viewer)) call('%s %s' % (viewer, output_file), shell=True, stdout=PIPE, stderr=PIPE) + + tmp.cleanup() return @@ -1990,7 +1995,7 @@ def png(x, filename, density=150, debug=False, # path name for permanent png output abs_path_to_png = os.path.abspath(filename) # temporary directory to store stuff - tmp = tmp_dir('sage_viewer') + tmp = TemporaryDirectory() tex_file = os.path.join(tmp, "sage.tex") png_file = os.path.join(tmp, "sage.png") # write latex string to file @@ -2004,6 +2009,8 @@ def png(x, filename, density=150, debug=False, shutil.copy(png_file, abs_path_to_png) else: print("Latex error") + + tmp.cleanup() if debug: return s return From db73fe945ff5a8fc4152e98738170afa452da20a Mon Sep 17 00:00:00 2001 From: Michael Orlitzky Date: Fri, 22 Sep 2023 18:49:29 -0400 Subject: [PATCH 123/216] src/sage/parallel/map_reduce.py: logger.warn -> logger.warning Fixes a DeprecationWarning: DeprecationWarning: The 'warn' method is deprecated, use 'warning' instead logger.warn(f"Profiling in {output} ...") --- src/sage/parallel/map_reduce.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/parallel/map_reduce.py b/src/sage/parallel/map_reduce.py index 11e0673ee91..916bfa32e63 100644 --- a/src/sage/parallel/map_reduce.py +++ b/src/sage/parallel/map_reduce.py @@ -1713,7 +1713,7 @@ def run(self): PROFILER.runcall(self.run_myself) output = profile + str(self._iproc) - logger.warn(f"Profiling in {output} ...") + logger.warning(f"Profiling in {output} ...") PROFILER.dump_stats(output) else: self.run_myself() From ee0d8ef3c8a331f39c37a5cb686a1bf22d1fdb2e Mon Sep 17 00:00:00 2001 From: Michael Orlitzky Date: Fri, 22 Sep 2023 18:50:03 -0400 Subject: [PATCH 124/216] src/sage/parallel/map_reduce.py: replace tmp_dir() Standard tempfile.TemporaryDirectory() replacement. Issue: https://github.com/sagemath/sage/issues/36322 --- src/sage/parallel/map_reduce.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/sage/parallel/map_reduce.py b/src/sage/parallel/map_reduce.py index 916bfa32e63..76b5c4bd549 100644 --- a/src/sage/parallel/map_reduce.py +++ b/src/sage/parallel/map_reduce.py @@ -293,8 +293,9 @@ The profiling is activated by the ``profile`` parameter. The value provided should be a prefix (including a possible directory) for the profile dump:: - sage: prof = tmp_dir('RESetMR_profile') + 'profcomp' - sage: res = S.run(profile=prof) # random + sage: import tempfile + sage: d = tempfile.TemporaryDirectory(prefix="RESetMR_profile") + sage: res = S.run(profile=d.name) # random [RESetMapReduceWorker-1:58] (20:00:41.444) Profiling in /home/user/.sage/temp/.../32414/RESetMR_profilewRCRAx/profcomp1 ... @@ -309,7 +310,7 @@ :class:`cProfile.Profile` for more details:: sage: import cProfile, pstats - sage: st = pstats.Stats(prof+'0') + sage: st = pstats.Stats(d.name+'0') sage: st.strip_dirs().sort_stats('cumulative').print_stats() # random ... Ordered by: cumulative time @@ -320,6 +321,11 @@ ... +Like a good neighbor we clean up our temporary directory as soon as +possible:: + + sage: d.cleanup() + .. SEEALSO:: `The Python Profilers `_ From 73ab316abb4ffef3953b46bf0620d4a4cb2866e1 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 9 Oct 2023 19:47:55 -0700 Subject: [PATCH 125/216] bootstrap-conda (src/environment-dev*.yml): Suppress pip section, for now --- bootstrap-conda | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bootstrap-conda b/bootstrap-conda index 19e56e3c5fa..faa29513db4 100755 --- a/bootstrap-conda +++ b/bootstrap-conda @@ -151,7 +151,7 @@ echo >&2 $0:$LINENO: generate conda environment files done fi done - ) 4>> src/environment-dev-template.yml 5>> src/environment-optional-template.yml + ) 4>> /dev/null 5>> src/environment-optional-template.yml for f in environment environment-optional src/environment src/environment-optional src/environment-dev; do for python_version in 3.9 3.10 3.11; do From 3e9dddb06ad0d03932ed0f80590c45b594c055dd Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 9 Oct 2023 19:20:23 -0700 Subject: [PATCH 126/216] .github/workflows/dist.yml: Create release on release tag --- .github/workflows/dist.yml | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/.github/workflows/dist.yml b/.github/workflows/dist.yml index 3aaecc6a064..834041d1fca 100644 --- a/.github/workflows/dist.yml +++ b/.github/workflows/dist.yml @@ -39,12 +39,34 @@ jobs: sudo DEBIAN_FRONTEND=noninteractive apt-get install $(build/bin/sage-get-system-packages debian _bootstrap) - name: make dist run: | - ./bootstrap -D && ./configure --disable-download-from-upstream-url && make dist + ./bootstrap -D && ./configure && make dist + env: + MAKE: make -j8 - uses: actions/upload-artifact@v3 with: - path: "dist/*.tar.gz" + path: | + dist/*.tar.gz + upstream name: release_dist + release: + + needs: release_dist + runs-on: ubuntu-latest + if: github.repository == 'sagemath/sage' && startsWith(github.ref, 'refs/tags/') && ! contains(github.ref, 'beta') && !contains(github.ref, 'rc') + steps: + - uses: actions/download-artifact@v3 + with: + name: release_dist + - uses: softprops/action-gh-release@v1 + with: + generate_release_notes: true + files: | + dist/* + upstream/* + permissions: + contents: write + sdists_for_pypi: runs-on: ubuntu-latest From 8ee6738e7a773893e578a0e4615995d9a4512faa Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 9 Oct 2023 21:33:38 -0700 Subject: [PATCH 127/216] .github/workflows/dist.yml (release_dist): First try without upstream_url, then fall back to with --- .github/workflows/dist.yml | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/.github/workflows/dist.yml b/.github/workflows/dist.yml index 834041d1fca..de49bbc69a3 100644 --- a/.github/workflows/dist.yml +++ b/.github/workflows/dist.yml @@ -18,9 +18,8 @@ jobs: release_dist: - # This job, in contrast to "dist" in ci-macos.yml, - # does not use "configure --enable-download-from-upstream-url" - # (the default since #32390). + # This job first checks whether "configure --enable-download-from-upstream-url" + # (the default since #32390) is needed. # # In this way, we check that all necessary package tarballs # have already been uploaded to the Sage server at the time @@ -37,12 +36,19 @@ jobs: run: | sudo DEBIAN_FRONTEND=noninteractive apt-get update sudo DEBIAN_FRONTEND=noninteractive apt-get install $(build/bin/sage-get-system-packages debian _bootstrap) - - name: make dist + - name: make dist (--disable-download-from-upstream-url) run: | - ./bootstrap -D && ./configure && make dist + ./bootstrap -D && ./configure --disable-download-from-upstream-url && make dist + env: + MAKE: make -j8 + - name: make dist (--enable-download-from-upstream-url) + if: failure() + run: | + ./configure && make dist env: MAKE: make -j8 - uses: actions/upload-artifact@v3 + if: success() || failure() with: path: | dist/*.tar.gz @@ -53,7 +59,7 @@ jobs: needs: release_dist runs-on: ubuntu-latest - if: github.repository == 'sagemath/sage' && startsWith(github.ref, 'refs/tags/') && ! contains(github.ref, 'beta') && !contains(github.ref, 'rc') + if: (success() || failure()) && github.repository == 'sagemath/sage' && startsWith(github.ref, 'refs/tags/') && !contains(github.ref, 'beta') && !contains(github.ref, 'rc') steps: - uses: actions/download-artifact@v3 with: From 21c0e961ebad7e24c7efdc5309b171ba55e7b6af Mon Sep 17 00:00:00 2001 From: DavidAyotte Date: Tue, 10 Oct 2023 09:03:28 -0400 Subject: [PATCH 128/216] add charzero Drinfeld modules to reference manual --- src/doc/en/reference/drinfeld_modules/index.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/src/doc/en/reference/drinfeld_modules/index.rst b/src/doc/en/reference/drinfeld_modules/index.rst index d7485c9762e..1aa080d7475 100644 --- a/src/doc/en/reference/drinfeld_modules/index.rst +++ b/src/doc/en/reference/drinfeld_modules/index.rst @@ -12,6 +12,7 @@ Drinfeld modules :maxdepth: 2 sage/rings/function_field/drinfeld_modules/drinfeld_module + sage/rings/function_field/drinfeld_modules/charzero_drinfeld_module sage/rings/function_field/drinfeld_modules/finite_drinfeld_module Morphisms and isogenies From 9a9bb5883c150597a997f50c746add8cc695df62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Tue, 10 Oct 2023 17:05:42 +0200 Subject: [PATCH 129/216] trying ruff on some posets files --- .../combinat/posets/incidence_algebras.py | 5 ++- src/sage/combinat/posets/posets.py | 35 +++++++++---------- 2 files changed, 18 insertions(+), 22 deletions(-) diff --git a/src/sage/combinat/posets/incidence_algebras.py b/src/sage/combinat/posets/incidence_algebras.py index dfd18f8c338..943fb69fde9 100644 --- a/src/sage/combinat/posets/incidence_algebras.py +++ b/src/sage/combinat/posets/incidence_algebras.py @@ -58,7 +58,7 @@ def __init__(self, R, P, prefix='I'): TESTS:: - sage: P = posets.BooleanLattice(4) + sage: P = posets.BooleanLattice(3) sage: I = P.incidence_algebra(QQ) sage: TestSuite(I).run() # long time """ @@ -93,8 +93,7 @@ def _repr_(self): Incidence algebra of Finite lattice containing 16 elements over Rational Field """ - return "Incidence algebra of {} over {}".format(self._poset, - self.base_ring()) + return f"Incidence algebra of {self._poset} over {self.base_ring()}" def _coerce_map_from_(self, R): """ diff --git a/src/sage/combinat/posets/posets.py b/src/sage/combinat/posets/posets.py index 0963c2b9d31..519b4aeb71d 100644 --- a/src/sage/combinat/posets/posets.py +++ b/src/sage/combinat/posets/posets.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # sage.doctest: needs sage.graphs sage.modules r""" Finite posets @@ -287,9 +286,8 @@ # **************************************************************************** from __future__ import annotations from collections import defaultdict -from copy import copy, deepcopy +from copy import copy from itertools import product -from typing import List from sage.misc.cachefunc import cached_method from sage.misc.lazy_attribute import lazy_attribute @@ -706,7 +704,7 @@ def Poset(data=None, element_labels=None, cover_relations=False, linear_extensio if data is None: # type 0 D = DiGraph() elif isinstance(data, DiGraph): # type 4 - D = deepcopy(data) + D = data.copy(immutable=True) elif isinstance(data, dict): # type 3: dictionary of upper covers D = DiGraph(data, format="dict_of_lists") elif isinstance(data, (list, tuple)): # types 1, 2, 3 (list/tuple) @@ -1319,7 +1317,7 @@ def __call__(self, element): """ if self._is_facade and element in self._element_to_vertex_dict: return element - return super(FinitePoset, self).__call__(element) + return super().__call__(element) def hasse_diagram(self): r""" @@ -1403,7 +1401,7 @@ def _repr_(self): sage: M._repr_() 'Finite meet-semilattice containing 3 elements' """ - s = "%s containing %s elements" % (self._desc, self._hasse_diagram.order()) + s = f"{self._desc} containing {self._hasse_diagram.order()} elements" if self._with_linear_extension: s += " with distinguished linear extension" return s @@ -1444,13 +1442,13 @@ def _rich_repr_(self, display_manager, **kwds): return output # create text for non-graphical output if can_plot: - text = '{0} (use the .plot() method to plot)'.format(repr(self)) + text = f'{repr(self)} (use the .plot() method to plot)' else: text = repr(self) # latex() produces huge tikz environment, override tp = display_manager.types if (prefs.text == 'latex' and tp.OutputLatex in display_manager.supported_output()): - return tp.OutputLatex(r'\text{{{0}}}'.format(text)) + return tp.OutputLatex(fr'\text{{{text}}}') return tp.OutputPlainText(text) def __iter__(self): @@ -2669,7 +2667,7 @@ def relations_number(self): # Maybe this should also be deprecated. intervals_number = relations_number - def linear_intervals_count(self) -> List[int]: + def linear_intervals_count(self) -> list[int]: """ Return the enumeration of linear intervals w.r.t. their cardinality. @@ -2799,10 +2797,10 @@ def is_incomparable_chain_free(self, m, n=None) -> bool: sage: Q = Poset({0:[2], 1:[2], 2:[3], 3:[4], 4:[]}) sage: Q.is_incomparable_chain_free(2, 20/10) True - sage: Q.is_incomparable_chain_free(2, pi) # needs sage.symbolic + sage: Q.is_incomparable_chain_free(2, 1.5) Traceback (most recent call last): ... - TypeError: 2 and pi must be integers + TypeError: 2 and 1.5... must be integers sage: Q.is_incomparable_chain_free(2, -1) Traceback (most recent call last): ... @@ -2850,9 +2848,9 @@ def is_incomparable_chain_free(self, m, n=None) -> bool: try: m, n = Integer(m), Integer(n) except TypeError: - raise TypeError("%s and %s must be integers" % (m, n)) + raise TypeError(f"{m} and {n} must be integers") if m < 1 or n < 1: - raise ValueError("%s and %s must be positive integers" % (m, n)) + raise ValueError(f"{m} and {n} must be positive integers") twochains = digraphs.TransitiveTournament(m) + digraphs.TransitiveTournament(n) if closure.subgraph_search(twochains, induced=True) is not None: return False @@ -6348,7 +6346,7 @@ def graphviz_string(self, graph_string="graph", edge_string="--"): s += '"%s";' % v s += '\n' for u, v in self.cover_relations_iterator(): - s += '"%s"%s"%s";' % (v, edge_string, u) + s += f'"{v}"{edge_string}"{u}";' s += "\n}" return s @@ -8152,9 +8150,9 @@ def is_eulerian(self, k=None, certificate=False): try: k = Integer(k) except TypeError: - raise TypeError("parameter 'k' must be an integer, not {0}".format(k)) + raise TypeError(f"parameter 'k' must be an integer, not {k}") if k <= 0: - raise ValueError("parameter 'k' must be positive, not {0}".format(k)) + raise ValueError(f"parameter 'k' must be positive, not {k}") if not self.is_bounded(): raise ValueError("the poset is not bounded") @@ -8880,7 +8878,7 @@ def _macaulay2_init_(self, macaulay2=None): H = self._hasse_diagram txt = 'needsPackage "Posets";' txt += "poset({%s},{" % ','.join(str(x) for x in H) - txt += ",".join("{%s,%s}" % (str(x), str(y)) + txt += ",".join(f"{{{str(x)},{str(y)}}}" for x, y in H.cover_relations_iterator()) return txt + "})" @@ -8993,8 +8991,7 @@ def cardinality(self, from_iterator=False): 68275077901156, 4483130665195087] if not from_iterator and self._n < len(known_values): return Integer(known_values[self._n]) - else: - return super(FinitePosets_n, self).cardinality() + return super().cardinality() # For backward compatibility of pickles of the former Posets() From 0c4578fe8965ea8b0f1531a6bf8d3ba3707b07c6 Mon Sep 17 00:00:00 2001 From: Michael Orlitzky Date: Tue, 10 Oct 2023 12:01:42 -0400 Subject: [PATCH 130/216] src/sage/misc/latex.py: use context manager for TemporaryDirectory() This is less error-prone than calling cleanup() manually, although it results in a much larger diff. --- src/sage/misc/latex.py | 147 ++++++++++++++++++++--------------------- 1 file changed, 73 insertions(+), 74 deletions(-) diff --git a/src/sage/misc/latex.py b/src/sage/misc/latex.py index ca99e298a8d..e0d32725cec 100644 --- a/src/sage/misc/latex.py +++ b/src/sage/misc/latex.py @@ -1104,44 +1104,47 @@ def eval(self, x, globals, strip=False, filename=None, debug=None, else: filename = os.path.splitext(filename)[0] # get rid of extension - base = TemporaryDirectory() - orig_base, filename = os.path.split(os.path.abspath(filename)) - if len(filename.split()) > 1: - raise ValueError("filename must contain no spaces") - if debug is None: - debug = self.__debug - x = self._latex_preparse(x, locals) - O = open(os.path.join(base, filename + ".tex"), 'w') - if self.__slide: - O.write(SLIDE_HEADER) - O.write(MACROS) - O.write('\\begin{document}\n\n') - else: - O.write(LATEX_HEADER) - O.write(MACROS) - O.write('\\begin{document}\n') - - O.write(x) - if self.__slide: - O.write('\n\n\\end{document}') - else: - O.write('\n\n\\end{document}\n') + result = None + with TemporaryDirectory() as base: + orig_base, filename = os.path.split(os.path.abspath(filename)) + if len(filename.split()) > 1: + raise ValueError("filename must contain no spaces") + if debug is None: + debug = self.__debug + x = self._latex_preparse(x, locals) + O = open(os.path.join(base, filename + ".tex"), 'w') + if self.__slide: + O.write(SLIDE_HEADER) + O.write(MACROS) + O.write('\\begin{document}\n\n') + else: + O.write(LATEX_HEADER) + O.write(MACROS) + O.write('\\begin{document}\n') - O.close() - if engine is None: - if self.__engine is None: - engine = _Latex_prefs._option["engine"] + O.write(x) + if self.__slide: + O.write('\n\n\\end{document}') else: - engine = self.__engine - e = _run_latex_(os.path.join(base, filename + ".tex"), debug=debug, - density=density, engine=engine, png=True) - result = None - if e.find("Error") == -1: - shutil.copy(os.path.join(base, filename + ".png"), - os.path.join(orig_base, filename + ".png")) - result = '' + O.write('\n\n\\end{document}\n') + + O.close() + if engine is None: + if self.__engine is None: + engine = _Latex_prefs._option["engine"] + else: + engine = self.__engine + e = _run_latex_(os.path.join(base, filename + ".tex"), + debug=debug, + density=density, + engine=engine, + png=True) + + if e.find("Error") == -1: + shutil.copy(os.path.join(base, filename + ".png"), + os.path.join(orig_base, filename + ".png")) + result = '' - base.cleanup() return result def blackboard_bold(self, t=None): @@ -1920,30 +1923,27 @@ def view(objects, title='Sage', debug=False, sep='', tiny=False, if pdflatex or (viewer == "pdf" and engine == "latex"): engine = "pdflatex" # command line or notebook with viewer - tmp = TemporaryDirectory() - tex_file = os.path.join(tmp, "sage.tex") - with open(tex_file, 'w') as file: - file.write(s) - suffix = _run_latex_(tex_file, debug=debug, engine=engine, png=False) - if suffix == "pdf": - from sage.misc.viewer import pdf_viewer - viewer = pdf_viewer() - elif suffix == "dvi": - from sage.misc.viewer import dvi_viewer - viewer = dvi_viewer() - else: - print("Latex error") - tmp.cleanup() - return - output_file = os.path.join(tmp, "sage." + suffix) - # this should get changed if we switch the stuff in misc.viewer to - # producing lists - if debug: - print('viewer: "{}"'.format(viewer)) - call('%s %s' % (viewer, output_file), shell=True, - stdout=PIPE, stderr=PIPE) - - tmp.cleanup() + with TemporaryDirectory() as tmp: + tex_file = os.path.join(tmp, "sage.tex") + with open(tex_file, 'w') as file: + file.write(s) + suffix = _run_latex_(tex_file, debug=debug, engine=engine, png=False) + if suffix == "pdf": + from sage.misc.viewer import pdf_viewer + viewer = pdf_viewer() + elif suffix == "dvi": + from sage.misc.viewer import dvi_viewer + viewer = dvi_viewer() + else: + print("Latex error") + return + output_file = os.path.join(tmp, "sage." + suffix) + # this should get changed if we switch the stuff in misc.viewer to + # producing lists + if debug: + print('viewer: "{}"'.format(viewer)) + call('%s %s' % (viewer, output_file), shell=True, + stdout=PIPE, stderr=PIPE) return @@ -1995,22 +1995,21 @@ def png(x, filename, density=150, debug=False, # path name for permanent png output abs_path_to_png = os.path.abspath(filename) # temporary directory to store stuff - tmp = TemporaryDirectory() - tex_file = os.path.join(tmp, "sage.tex") - png_file = os.path.join(tmp, "sage.png") - # write latex string to file - with open(tex_file, 'w') as file: - file.write(s) - # run latex on the file, producing png output to png_file - e = _run_latex_(tex_file, density=density, debug=debug, - png=True, engine=engine) - if e.find("Error") == -1: - # if no errors, copy png_file to the appropriate place - shutil.copy(png_file, abs_path_to_png) - else: - print("Latex error") + with TemporaryDirectory() as tmp: + tex_file = os.path.join(tmp, "sage.tex") + png_file = os.path.join(tmp, "sage.png") + # write latex string to file + with open(tex_file, 'w') as file: + file.write(s) + # run latex on the file, producing png output to png_file + e = _run_latex_(tex_file, density=density, debug=debug, + png=True, engine=engine) + if e.find("Error") == -1: + # if no errors, copy png_file to the appropriate place + shutil.copy(png_file, abs_path_to_png) + else: + print("Latex error") - tmp.cleanup() if debug: return s return From 56f0e29a7a06f16a73f0b77aaa5121b0d90a44d1 Mon Sep 17 00:00:00 2001 From: DavidAyotte Date: Tue, 10 Oct 2023 13:16:08 -0400 Subject: [PATCH 131/216] add documention about different base fields of charzero --- .../charzero_drinfeld_module.py | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/sage/rings/function_field/drinfeld_modules/charzero_drinfeld_module.py b/src/sage/rings/function_field/drinfeld_modules/charzero_drinfeld_module.py index 08b3c6622a3..74a73a8168d 100644 --- a/src/sage/rings/function_field/drinfeld_modules/charzero_drinfeld_module.py +++ b/src/sage/rings/function_field/drinfeld_modules/charzero_drinfeld_module.py @@ -90,6 +90,28 @@ class DrinfeldModule_charzero(DrinfeldModule): X^2 sage: phi.goss_polynomial(3) X^3 + (1/(T^2 + T))*X^2 + + .. RUBRIC:: Base fields of `\mathbb{F}_q[T]`-characteristic zero + + The base fields need not only be fraction fields of polynomials + ring. In the following example, we construct a Drinfeld module over + `\mathbb{F}_q((1/T))`, the completion of the rational function field + at the place `1/T`:: + + sage: A. = GF(2)[] + sage: L. = LaurentSeriesRing(GF(2)) # s = 1/T + sage: phi = DrinfeldModule(A, [1/s, s + s^2 + s^5 + O(s^6), 1+1/s]) + sage: phi(T) + (s^-1 + 1)*t^2 + (s + s^2 + s^5 + O(s^6))*t + s^-1 + + One can also construct Drinfeld modules over SageMath's global + function fields:: + + sage: A. = GF(5)[] + sage: K. = FunctionField(GF(5)) # z = T + sage: phi = DrinfeldModule(A, [z, 1, z^2]) + sage: phi(T) + z^2*t^2 + t + z """ @cached_method def _compute_coefficient_exp(self, k): From f4299939f1636afe30f5fca76547e4fde5942985 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 10 Oct 2023 10:23:38 -0700 Subject: [PATCH 132/216] .ci/retrofit-worktree.sh: New, factored out from .github/workflows/build*.yml --- .ci/retrofit-worktree.sh | 39 +++++++++++++++++++++++++++++ .github/workflows/build.yml | 24 +----------------- .github/workflows/doc-build-pdf.yml | 25 +----------------- .github/workflows/doc-build.yml | 25 +----------------- 4 files changed, 42 insertions(+), 71 deletions(-) create mode 100755 .ci/retrofit-worktree.sh diff --git a/.ci/retrofit-worktree.sh b/.ci/retrofit-worktree.sh new file mode 100755 index 00000000000..f926e59059e --- /dev/null +++ b/.ci/retrofit-worktree.sh @@ -0,0 +1,39 @@ +#!/bin/sh +if [ $# != 2 ]; then + echo >&2 "usage: $0 WORKTREE_NAME WORKTREE_DIRECTORY" + echo >&2 "Ensures that the current working directory is a git repository," + echo >&2 "then makes WORKTREE_DIRECTORY a git worktree named WORKTREE_NAME." +fi +WORKTREE_NAME="$1" +WORKTREE_DIRECTORY="$2" + +export GIT_AUTHOR_NAME="ci-sage workflow" +export GIT_AUTHOR_EMAIL="ci-sage@example.com" +export GIT_COMMITTER_NAME="$GIT_AUTHOR_NAME" +export GIT_COMMITTER_EMAIL="$GIT_AUTHOR_EMAIL" + +set -ex + +# If actions/checkout downloaded our source tree using the GitHub REST API +# instead of with git (because do not have git installed in our image), +# we first make the source tree a repo. +if [ ! -d .git ]; then git init && git add -A && git commit --quiet -m "new"; fi + +# Tag this state of the source tree "new". This is what we want to build and test. +git tag -f new + +# Our container image contains a source tree in $WORKTREE_DIRECTORY with a full build of Sage. +# But $WORKTREE_DIRECTORY is not a git repository. +# We make $WORKTREE_DIRECTORY a worktree whose index is at tag "new". +# We then commit the current sources and set the tag "old". (This keeps all mtimes unchanged.) +# Then we update worktree and index with "git reset --hard new". +# (This keeps mtimes of unchanged files unchanged and mtimes of changed files newer than unchanged files.) +# Finally we reset the index to "old". (This keeps all mtimes unchanged.) +# The changed files now show up as uncommitted changes. +# The final "git add -N" makes sure that files that were added in "new" do not show +# as untracked files, which would be removed by "git clean -fx". +git worktree add --detach $WORKTREE_NAME +rm -rf $WORKTREE_DIRECTORY/.git && mv $WORKTREE_NAME/.git $WORKTREE_DIRECTORY/ +rm -rf $WORKTREE_NAME && ln -s $WORKTREE_DIRECTORY $WORKTREE_NAME +if [ ! -f $WORKTREE_NAME/.gitignore ]; then cp .gitignore $WORKTREE_NAME/; fi +(cd $WORKTREE_NAME && git add -A && git commit --quiet --allow-empty -m "old" -a && git tag -f old && git reset --hard new && git reset --quiet old && git add -N . && git status) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 062fa973ac3..89ed87ecf91 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -69,30 +69,8 @@ jobs: id: worktree run: | set -ex - git config --global user.email "ci-sage@example.com" - git config --global user.name "Build & Test workflow" git config --global --add safe.directory $(pwd) - # If actions/checkout downloaded our source tree using the GitHub REST API - # instead of with git (because do not have git installed in our image), - # we first make the source tree a repo. - if [ ! -d .git ]; then git init && git add -A && git commit --quiet -m "new"; fi - # Tag this state of the source tree "new". This is what we want to build and test. - git tag -f new - # Our container image contains a source tree in /sage with a full build of Sage. - # But /sage is not a git repository. - # We make /sage a worktree whose index is at tag "new". - # We then commit the current sources and set the tag "old". (This keeps all mtimes unchanged.) - # Then we update worktree and index with "git reset --hard new". - # (This keeps mtimes of unchanged files unchanged and mtimes of changed files newer than unchanged files.) - # Finally we reset the index to "old". (This keeps all mtimes unchanged.) - # The changed files now show up as uncommitted changes. - # The final "git add -N" makes sure that files that were added in "new" do not show - # as untracked files, which would be removed by "git clean -fx". - git worktree add --detach worktree-image - rm -rf /sage/.git && mv worktree-image/.git /sage/ - rm -rf worktree-image && ln -s /sage worktree-image - if [ ! -f worktree-image/.gitignore ]; then cp .gitignore worktree-image/; fi - (cd worktree-image && git add -A && git commit --quiet --allow-empty -m "old" -a && git tag -f old && git reset --hard new && git reset --quiet old && git add -N . && git status) + .ci/retrofit-worktree.sh worktree-image /sage - name: Download upstream artifact uses: actions/download-artifact@v3 diff --git a/.github/workflows/doc-build-pdf.yml b/.github/workflows/doc-build-pdf.yml index 0413954210b..34c96e70a40 100644 --- a/.github/workflows/doc-build-pdf.yml +++ b/.github/workflows/doc-build-pdf.yml @@ -62,31 +62,8 @@ jobs: - name: Add prebuilt tree as a worktree id: worktree run: | - set -ex - git config --global user.email "ci-sage@example.com" - git config --global user.name "Build & Test workflow" git config --global --add safe.directory $(pwd) - # If actions/checkout downloaded our source tree using the GitHub REST API - # instead of with git (because do not have git installed in our image), - # we first make the source tree a repo. - if [ ! -d .git ]; then git init && git add -A && git commit --quiet -m "new"; fi - # Tag this state of the source tree "new". This is what we want to build and test. - git tag -f new - # Our container image contains a source tree in /sage with a full build of Sage. - # But /sage is not a git repository. - # We make /sage a worktree whose index is at tag "new". - # We then commit the current sources and set the tag "old". (This keeps all mtimes unchanged.) - # Then we update worktree and index with "git reset --hard new". - # (This keeps mtimes of unchanged files unchanged and mtimes of changed files newer than unchanged files.) - # Finally we reset the index to "old". (This keeps all mtimes unchanged.) - # The changed files now show up as uncommitted changes. - # The final "git add -N" makes sure that files that were added in "new" do not show - # as untracked files, which would be removed by "git clean -fx". - git worktree add --detach worktree-image - rm -rf /sage/.git && mv worktree-image/.git /sage/ - rm -rf worktree-image && ln -s /sage worktree-image - if [ ! -f worktree-image/.gitignore ]; then cp .gitignore worktree-image/; fi - (cd worktree-image && git add -A && git commit --quiet --allow-empty -m "old" -a && git tag -f old && git reset --hard new && git reset --quiet old && git add -N . && git status) + .ci/retrofit-worktree.sh worktree-image /sage # Keep track of changes to built HTML new_version=$(cat src/VERSION.txt); (cd /sage/local/share/doc/sage/html/en && find . -name "*.html" | xargs sed -i '/class="sidebar-brand-text"/s/Sage [0-9a-z.]* /Sage '$new_version' /'; git init && (echo "*.svg binary"; echo "*.pdf binary") >> .gitattributes && (echo ".buildinfo"; echo '*.inv'; echo '.git*'; echo '*.svg'; echo '*.pdf'; echo '*.png'; echo 'searchindex.js') > .gitignore; git add -A && git commit --quiet -m "old") diff --git a/.github/workflows/doc-build.yml b/.github/workflows/doc-build.yml index 355e07ab78e..31354c8e531 100644 --- a/.github/workflows/doc-build.yml +++ b/.github/workflows/doc-build.yml @@ -53,31 +53,8 @@ jobs: - name: Add prebuilt tree as a worktree id: worktree run: | - set -ex - git config --global user.email "ci-sage@example.com" - git config --global user.name "Build & Test workflow" git config --global --add safe.directory $(pwd) - # If actions/checkout downloaded our source tree using the GitHub REST API - # instead of with git (because do not have git installed in our image), - # we first make the source tree a repo. - if [ ! -d .git ]; then git init && git add -A && git commit --quiet -m "new"; fi - # Tag this state of the source tree "new". This is what we want to build and test. - git tag -f new - # Our container image contains a source tree in /sage with a full build of Sage. - # But /sage is not a git repository. - # We make /sage a worktree whose index is at tag "new". - # We then commit the current sources and set the tag "old". (This keeps all mtimes unchanged.) - # Then we update worktree and index with "git reset --hard new". - # (This keeps mtimes of unchanged files unchanged and mtimes of changed files newer than unchanged files.) - # Finally we reset the index to "old". (This keeps all mtimes unchanged.) - # The changed files now show up as uncommitted changes. - # The final "git add -N" makes sure that files that were added in "new" do not show - # as untracked files, which would be removed by "git clean -fx". - git worktree add --detach worktree-image - rm -rf /sage/.git && mv worktree-image/.git /sage/ - rm -rf worktree-image && ln -s /sage worktree-image - if [ ! -f worktree-image/.gitignore ]; then cp .gitignore worktree-image/; fi - (cd worktree-image && git add -A && git commit --quiet --allow-empty -m "old" -a && git tag -f old && git reset --hard new && git reset --quiet old && git add -N . && git status) + .ci/retrofit-worktree.sh worktree-image /sage # Keep track of changes to built HTML new_version=$(cat src/VERSION.txt); (cd /sage/local/share/doc/sage/html/en && find . -name "*.html" | xargs sed -i '/class="sidebar-brand-text"/s/Sage [0-9a-z.]* /Sage '$new_version' /'; git init && (echo "*.svg binary"; echo "*.pdf binary") >> .gitattributes && (echo ".buildinfo"; echo '*.inv'; echo '.git*'; echo '*.svg'; echo '*.pdf'; echo '*.png'; echo 'searchindex.js') > .gitignore; git add -A && git commit --quiet -m "old") From b2719f402ad54134ca3172ebefd4307ee768e11c Mon Sep 17 00:00:00 2001 From: "John H. Palmieri" Date: Tue, 10 Oct 2023 13:02:22 -0700 Subject: [PATCH 133/216] Delete one blank line. --- src/doc/ru/tutorial/tour_linalg.rst | 1 - 1 file changed, 1 deletion(-) diff --git a/src/doc/ru/tutorial/tour_linalg.rst b/src/doc/ru/tutorial/tour_linalg.rst index 6b4c64764c8..bf2a1084544 100644 --- a/src/doc/ru/tutorial/tour_linalg.rst +++ b/src/doc/ru/tutorial/tour_linalg.rst @@ -37,7 +37,6 @@ Sage поддерживает стандартные конструкции из sage: A * X # проверка... (0, -4, -1) - Если решения не существует, то Sage вернет ошибку: .. skip From 9069a3655b369133796935a641a23923a2a9bf6b Mon Sep 17 00:00:00 2001 From: DavidAyotte Date: Tue, 10 Oct 2023 16:25:58 -0400 Subject: [PATCH 134/216] address Xavier's comment --- .../function_field/drinfeld_modules/charzero_drinfeld_module.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/rings/function_field/drinfeld_modules/charzero_drinfeld_module.py b/src/sage/rings/function_field/drinfeld_modules/charzero_drinfeld_module.py index 74a73a8168d..49d6850f67c 100644 --- a/src/sage/rings/function_field/drinfeld_modules/charzero_drinfeld_module.py +++ b/src/sage/rings/function_field/drinfeld_modules/charzero_drinfeld_module.py @@ -1,6 +1,6 @@ # sage.doctest: optional - sage.rings.finite_rings r""" -Complex Drinfeld module +Drinfeld modules over rings of characteristic zero This module provides the class :class:`sage.rings.function_fields.drinfeld_module.charzero_drinfeld_module.DrinfeldModule_charzero`, From 202a17cf16126f0b82db004fe7a38a03bcba0244 Mon Sep 17 00:00:00 2001 From: Dave Witte Morris Date: Tue, 10 Oct 2023 16:41:54 -0600 Subject: [PATCH 135/216] ZeroDivisionError in gcd of sparse polynomials --- .../polynomial/polynomial_element_generic.py | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/sage/rings/polynomial/polynomial_element_generic.py b/src/sage/rings/polynomial/polynomial_element_generic.py index 58a6a4d2308..8f8a296b488 100644 --- a/src/sage/rings/polynomial/polynomial_element_generic.py +++ b/src/sage/rings/polynomial/polynomial_element_generic.py @@ -953,6 +953,17 @@ def gcd(self,other,algorithm=None): 1 sage: (6*x).gcd(9) 3 + + Check that :trac:`36427` is fixed:: + + sage: P = PolynomialRing(ZZ, "q", sparse=True) + sage: q = P.gen() + sage: 2*q^-100 + 2/q^100 + sage: gcd(1, q^100) + 1 + sage: gcd(q^0, q^100) + 1 """ from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing @@ -969,8 +980,8 @@ def gcd(self,other,algorithm=None): # sd = self.degree() od = other.degree() - if max(sd,od) < 100 or \ - min(len(self.__coeffs)/sd, len(other.__coeffs)/od) > .06: + if ((sd < 100 or len(self.__coeffs)/sd > .06) + and (od < 100 or len(other.__coeffs)/od > .06)): implementation = "FLINT" else: implementation = "NTL" From 94c8b8855aefaf5695fccda84bd47d57b8a4eacc Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 10 Oct 2023 21:06:19 -0700 Subject: [PATCH 136/216] Fixup --- .github/workflows/doc-build-pdf.yml | 2 ++ .github/workflows/doc-build.yml | 2 ++ 2 files changed, 4 insertions(+) diff --git a/.github/workflows/doc-build-pdf.yml b/.github/workflows/doc-build-pdf.yml index 34c96e70a40..50a836b3b10 100644 --- a/.github/workflows/doc-build-pdf.yml +++ b/.github/workflows/doc-build-pdf.yml @@ -63,6 +63,8 @@ jobs: id: worktree run: | git config --global --add safe.directory $(pwd) + git config --global user.email "ci-sage@example.com" + git config --global user.name "Build & Test workflow" .ci/retrofit-worktree.sh worktree-image /sage # Keep track of changes to built HTML new_version=$(cat src/VERSION.txt); (cd /sage/local/share/doc/sage/html/en && find . -name "*.html" | xargs sed -i '/class="sidebar-brand-text"/s/Sage [0-9a-z.]* /Sage '$new_version' /'; git init && (echo "*.svg binary"; echo "*.pdf binary") >> .gitattributes && (echo ".buildinfo"; echo '*.inv'; echo '.git*'; echo '*.svg'; echo '*.pdf'; echo '*.png'; echo 'searchindex.js') > .gitignore; git add -A && git commit --quiet -m "old") diff --git a/.github/workflows/doc-build.yml b/.github/workflows/doc-build.yml index 31354c8e531..f8b338f50d6 100644 --- a/.github/workflows/doc-build.yml +++ b/.github/workflows/doc-build.yml @@ -54,6 +54,8 @@ jobs: id: worktree run: | git config --global --add safe.directory $(pwd) + git config --global user.email "ci-sage@example.com" + git config --global user.name "Build & Test workflow" .ci/retrofit-worktree.sh worktree-image /sage # Keep track of changes to built HTML new_version=$(cat src/VERSION.txt); (cd /sage/local/share/doc/sage/html/en && find . -name "*.html" | xargs sed -i '/class="sidebar-brand-text"/s/Sage [0-9a-z.]* /Sage '$new_version' /'; git init && (echo "*.svg binary"; echo "*.pdf binary") >> .gitattributes && (echo ".buildinfo"; echo '*.inv'; echo '.git*'; echo '*.svg'; echo '*.pdf'; echo '*.png'; echo 'searchindex.js') > .gitignore; git add -A && git commit --quiet -m "old") From 4fa04164b141ab8dd0697bd118a8adf27dc7d37c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Wed, 11 Oct 2023 14:16:24 +0200 Subject: [PATCH 137/216] suggested details --- src/sage/interacts/library.py | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/sage/interacts/library.py b/src/sage/interacts/library.py index 11035c241df..a8d3135c813 100644 --- a/src/sage/interacts/library.py +++ b/src/sage/interacts/library.py @@ -1337,25 +1337,28 @@ def parabola(a, b, c): html(r'Integral value to seven decimal places is: $\displaystyle\int_{%.2f}^{%.2f} {f(x) \, \mathrm{d}x} = %.6f$' % (interval[0],interval[1], - N(numeric_value,digits=7))) + N(numeric_value,digits=7))) if output_form == 'traditional': sum_formula_html = r"\frac{d}{3} \cdot \left[ f(x_0) + %s + f(x_{%s})\right]" % ( - ' + '.join([ r"%s \cdot f(x_{%s})" % (i % 2*(-2)+4, i+1) for i in range(0,n-1)]), + ' + '.join(r"%s \cdot f(x_{%s})" % (i % 2 * (-2) + 4, i + 1) + for i in range(0,n-1)), n ) sum_placement_html = r"\frac{%.2f}{3} \cdot \left[ f(%.2f) + %s + f(%.2f)\right]" % ( dx, N(xs[0],digits=5), - ' + '.join([ r"%s \cdot f(%.2f)" % (i % 2*(-2)+4, N(xk, digits=5)) for i, xk in enumerate(xs[1:-1])]), + ' + '.join(r"%s \cdot f(%.2f)" % (i % 2 * (-2) + 4, N(xk, digits=5)) + for i, xk in enumerate(xs[1:-1])), N(xs[n],digits=5) ) sum_values_html = r"\frac{%.2f}{3} \cdot \left[ %s %s %s\right]" % ( dx, "%.2f + " % N(ys[0],digits=5), - ' + '.join([ r"%s \cdot %.2f" % (i % 2*(-2)+4, N(yk, digits=5)) for i, yk in enumerate(ys[1:-1])]), + ' + '.join(r"%s \cdot %.2f" % (i % 2 * (-2) + 4, N(yk, digits=5)) + for i, yk in enumerate(ys[1:-1])), " + %.2f" % N(ys[n],digits=5) ) @@ -1376,12 +1379,12 @@ def parabola(a, b, c): )) elif output_form == 'table': s = [['$i$', '$x_i$', '$f(x_i)$', '$m$', r'$m\cdot f(x_i)$']] - for i in range(0,n+1): + for i in range(n + 1): if i == 0 or i == n: j = 1 else: - j = (i+1) % 2*(-2)+4 - s.append([i, xs[i], ys[i],j,N(j*ys[i])]) + j = (i + 1) % 2*(-2) + 4 + s.append([i, xs[i], ys[i], j, N(j*ys[i])]) s.append(['', '', '', r'$\sum$', '$%s$' % latex(3/dx*approx)]) pretty_print(table(s, header_row=True)) html(r'$\int_{%.2f}^{%.2f} {f(x) \, \mathrm{d}x}\approx\frac {%.2f}{3}\cdot %s=%s$' % From ebb688f159373aebd3da0480dcd9322aa60acfd5 Mon Sep 17 00:00:00 2001 From: David Ayotte <34245930+DavidAyotte@users.noreply.github.com> Date: Wed, 11 Oct 2023 09:51:38 -0400 Subject: [PATCH 138/216] Update src/sage/rings/function_field/drinfeld_modules/charzero_drinfeld_module.py Co-authored-by: Xavier Caruso --- .../drinfeld_modules/charzero_drinfeld_module.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/sage/rings/function_field/drinfeld_modules/charzero_drinfeld_module.py b/src/sage/rings/function_field/drinfeld_modules/charzero_drinfeld_module.py index 49d6850f67c..f7e0226b05e 100644 --- a/src/sage/rings/function_field/drinfeld_modules/charzero_drinfeld_module.py +++ b/src/sage/rings/function_field/drinfeld_modules/charzero_drinfeld_module.py @@ -327,8 +327,9 @@ def logarithm(self, name='z'): def coeff_log(k): # Return the k-th coefficient of the logarithm k = ZZ(k) - if k.is_power_of(q): - return self._compute_coefficient_log(k.log(q)) + v, u = k.val_unit(q) + if u == 1: + return self._compute_coefficient_log(v) else: return self._base.zero() return L(coeff_log, valuation=1) From 771688f639224f672c1387e939a6d12e528d7db6 Mon Sep 17 00:00:00 2001 From: David Ayotte <34245930+DavidAyotte@users.noreply.github.com> Date: Wed, 11 Oct 2023 09:52:04 -0400 Subject: [PATCH 139/216] Update src/sage/rings/function_field/drinfeld_modules/charzero_drinfeld_module.py Co-authored-by: Xavier Caruso --- .../drinfeld_modules/charzero_drinfeld_module.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/sage/rings/function_field/drinfeld_modules/charzero_drinfeld_module.py b/src/sage/rings/function_field/drinfeld_modules/charzero_drinfeld_module.py index f7e0226b05e..f50cc843e53 100644 --- a/src/sage/rings/function_field/drinfeld_modules/charzero_drinfeld_module.py +++ b/src/sage/rings/function_field/drinfeld_modules/charzero_drinfeld_module.py @@ -224,8 +224,9 @@ def exponential(self, name='z'): def coeff_exp(k): # Return the k-th coefficient of the exponential. k = ZZ(k) - if k.is_power_of(q): - return self._compute_coefficient_exp(k.log(q)) + v, u = k.val_unit(q) + if u == 1: + return self._compute_coefficient_exp(v) else: return zero return L(coeff_exp, valuation=1) From d90340e6634905beb1a1fee2136a9b9ac9463832 Mon Sep 17 00:00:00 2001 From: David Ayotte <34245930+DavidAyotte@users.noreply.github.com> Date: Wed, 11 Oct 2023 09:54:52 -0400 Subject: [PATCH 140/216] Update src/sage/rings/function_field/drinfeld_modules/charzero_drinfeld_module.py Co-authored-by: Xavier Caruso --- .../drinfeld_modules/charzero_drinfeld_module.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/sage/rings/function_field/drinfeld_modules/charzero_drinfeld_module.py b/src/sage/rings/function_field/drinfeld_modules/charzero_drinfeld_module.py index f50cc843e53..34644aef4a4 100644 --- a/src/sage/rings/function_field/drinfeld_modules/charzero_drinfeld_module.py +++ b/src/sage/rings/function_field/drinfeld_modules/charzero_drinfeld_module.py @@ -368,9 +368,13 @@ def _compute_goss_polynomial(self, n, q, poly_ring, X): if n % q == 0: return self.goss_polynomial(n // q)**q # General case - pol = sum(self._compute_coefficient_exp(i+1) - *self._compute_goss_polynomial(n - q**(i+1), q, poly_ring, X) - for i in range(0, (n.log(q).n()).floor())) + pol = poly_ring.zero() + m = q + i = 1 + while m < n: + pol += self._compute_coefficient_exp(i) * self._compute_goss_polynomial(n - m, q, poly_ring, X) + m *= q + i += 1 return X*(self._compute_goss_polynomial(n - 1, q, poly_ring, X) + pol) def goss_polynomial(self, n, var='X'): From d2cd838cecabb3d6fc1a964550e480b61d734f43 Mon Sep 17 00:00:00 2001 From: sheerluck Date: Wed, 11 Oct 2023 17:41:04 +0300 Subject: [PATCH 141/216] tox.ini: Add gentoo-python3.12 --- .github/workflows/docker.yml | 1 + tox.ini | 1 + 2 files changed, 2 insertions(+) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index d49aa516356..bbd6ff2160a 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -51,6 +51,7 @@ on: "almalinux-9-python3.11", "gentoo-python3.10", "gentoo-python3.11", + "gentoo-python3.12", "archlinux-latest", "opensuse-15.3-gcc_11-python3.9", "opensuse-15.4-gcc_11-python3.10", diff --git a/tox.ini b/tox.ini index c084e4c821e..4cd0e2ec5eb 100644 --- a/tox.ini +++ b/tox.ini @@ -325,6 +325,7 @@ setenv = gentoo: BASE_IMAGE=sheerluck/sage-on-gentoo-stage4 gentoo-python3.10: BASE_TAG=latest-py10 gentoo-python3.11: BASE_TAG=latest-py11 + gentoo-python3.12: BASE_TAG=latest-py12 gentoo: IGNORE_MISSING_SYSTEM_PACKAGES=no # # https://hub.docker.com/_/archlinux/ From 7ef92d2414665d6448d36acaadf5f7dd949945bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Wed, 11 Oct 2023 17:19:35 +0200 Subject: [PATCH 142/216] one more detail --- src/sage/interacts/library.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/interacts/library.py b/src/sage/interacts/library.py index a8d3135c813..83b5a93c006 100644 --- a/src/sage/interacts/library.py +++ b/src/sage/interacts/library.py @@ -1383,7 +1383,7 @@ def parabola(a, b, c): if i == 0 or i == n: j = 1 else: - j = (i + 1) % 2*(-2) + 4 + j = (i + 1) % 2 * (-2) + 4 s.append([i, xs[i], ys[i], j, N(j*ys[i])]) s.append(['', '', '', r'$\sum$', '$%s$' % latex(3/dx*approx)]) pretty_print(table(s, header_row=True)) From c7667b6f403e1b9e77a282d2d2fc4ecac8c6cff1 Mon Sep 17 00:00:00 2001 From: Sebastian Date: Wed, 11 Oct 2023 18:40:25 +0200 Subject: [PATCH 143/216] 36333: fix docstring --- src/sage/knots/link.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/sage/knots/link.py b/src/sage/knots/link.py index 9914f8bbcb5..224ca683a90 100644 --- a/src/sage/knots/link.py +++ b/src/sage/knots/link.py @@ -3099,7 +3099,8 @@ def is_colorable(self, n=None): INPUT: - - ``n`` -- the number of colors to consider + - ``n`` -- the number of colors to consider (if ommitted the + value of the determinant of ``self`` will be taken) EXAMPLES: From b427e02a3a0c7ee1f08580fb074e7e26ebd628ec Mon Sep 17 00:00:00 2001 From: Sebastian Date: Wed, 11 Oct 2023 18:50:22 +0200 Subject: [PATCH 144/216] 36385: add maintainer --- docker/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker/Dockerfile b/docker/Dockerfile index 359d59dd106..cc0701d8d81 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -76,7 +76,7 @@ ARG MAKE_BUILD=make-build # Image containing the run-time dependencies for Sage # ################################################################################ FROM ubuntu:jammy as run-time-dependencies -LABEL maintainer="Erik M. Bray , Julian Rüth " +LABEL maintainer="Erik M. Bray , Julian Rüth , Sebastian Oehms " # Set sane defaults for common environment variables. ENV LC_ALL C.UTF-8 ENV LANG C.UTF-8 From 4f66524cfc49a91d0365c6a8a7072c4f8bd85142 Mon Sep 17 00:00:00 2001 From: "Alex J. Best" Date: Wed, 11 Oct 2023 21:46:33 +0100 Subject: [PATCH 145/216] fix doctest --- src/sage/matrix/matrix0.pyx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/sage/matrix/matrix0.pyx b/src/sage/matrix/matrix0.pyx index 572936b9c42..f1542d9307e 100644 --- a/src/sage/matrix/matrix0.pyx +++ b/src/sage/matrix/matrix0.pyx @@ -5780,10 +5780,11 @@ cdef class Matrix(sage.structure.element.Matrix): Traceback (most recent call last): ... ArithmeticError: self must be a square matrix + sage: matrix(RR, 1, 1, [2]).inverse_of_unit() Traceback (most recent call last): ... - NotImplementedError: Lifting of multivariate polynomials over non-fields is not implemented. + ArithmeticError: non-invertible matrix sage: R = ZZ.cartesian_product(ZZ) sage: m = matrix(R, 2, [R((2,1)), R((1,1)), R((1,1)), R((1,2))]) From 18458bf3535e183c3315cd5763d7b09f3bef4b1e Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 11 Oct 2023 13:49:47 -0700 Subject: [PATCH 146/216] Rename spkg-piprm-requirements.txt to just spkg-requirements.txt --- build/bin/sage-dist-helpers | 2 +- build/bin/sage-spkg | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/build/bin/sage-dist-helpers b/build/bin/sage-dist-helpers index 67a2201d31f..567168b1f67 100644 --- a/build/bin/sage-dist-helpers +++ b/build/bin/sage-dist-helpers @@ -376,7 +376,7 @@ sdh_store_and_pip_install_wheel() { if [ -n "${SAGE_PKG_DIR}" ]; then # Record name of installed distribution name for uninstallation. wheel=${wheel##*/} - echo "${wheel%%-*}" >> ${SAGE_PKG_DIR}/spkg-piprm-requirements.txt + echo "${wheel%%-*}" >> ${SAGE_PKG_DIR}/spkg-requirements.txt fi } diff --git a/build/bin/sage-spkg b/build/bin/sage-spkg index 9b38ed6afc7..92c920d57cb 100755 --- a/build/bin/sage-spkg +++ b/build/bin/sage-spkg @@ -548,7 +548,7 @@ WRAPPED_SCRIPTS="build install check preinst postinst $INSTALLED_SCRIPTS" # Prepare script for uninstallation of packages that use sdh_pip_install # or sdh_store_and_pip_install_wheel. -echo 'sdh_pip_uninstall -r $SAGE_SPKG_SCRIPTS/$PKG_BASE/spkg-piprm-requirements.txt' > spkg-piprm.in +echo 'sdh_pip_uninstall -r $SAGE_SPKG_SCRIPTS/$PKG_BASE/spkg-requirements.txt' > spkg-piprm.in for script in $WRAPPED_SCRIPTS; do # 'Installed' scripts are not run immediately out of the package build @@ -722,7 +722,7 @@ unset SAGE_DESTDIR_LOCAL # removed by sage-spkg-uninstall INSTALLED_SCRIPTS_DEST="$SAGE_SPKG_SCRIPTS/$PKG_BASE" -if [ -f spkg-piprm-requirements.txt ]; then +if [ -f spkg-requirements.txt ]; then INSTALLED_SCRIPTS="$INSTALLED_SCRIPTS piprm-requirements.txt" else # No packages to uninstall with pip, so remove the prepared uninstall script From 4a4810e10c497c6d8d934a492f389abc0b5d9004 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 11 Oct 2023 12:36:36 -0700 Subject: [PATCH 147/216] build/make/Makefile.in (SCRIPT_PACKAGE_templ): Set more variables set by sage-spkg --- build/make/Makefile.in | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/build/make/Makefile.in b/build/make/Makefile.in index cc004d08c3c..d6e79c03547 100644 --- a/build/make/Makefile.in +++ b/build/make/Makefile.in @@ -730,7 +730,11 @@ $(1)-$(4)-no-deps: . '$$(SAGE_ROOT)/src/bin/sage-env' && \ . '$$(SAGE_ROOT)/build/bin/sage-build-env-config' && \ . '$$(SAGE_ROOT)/build/bin/sage-build-env' && \ + PKG_BASE="$(1)" \ + PKG_VER="$(2)" \ + PKG_NAME="$(1)-$(2)" \ SAGE_SPKG_WHEELS=$$($(4))/var/lib/sage/wheels \ + SAGE_SPKG_SCRIPTS=$$($(4))/var/lib/sage/scripts \ SAGE_INST_LOCAL=$$($(4)) \ sage-logger -p 'SAGE_CHECK=$$(SAGE_CHECK_$(1)) $$(SAGE_ROOT)/build/pkgs/$(1)/spkg-install' '$$(SAGE_LOGS)/$(1)-$(2).log' && \ rm -f "$$($(4))/$(SPKG_INST_RELDIR)/$(1)"-* && \ From 952405f3c1b131122821a9b1d673ac8a107ff987 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 11 Oct 2023 13:01:41 -0700 Subject: [PATCH 148/216] build/bin/sage-dist-helpers (sdh_store_[and_pip_install_]wheel): Record wheel file name in venv/var/lib/sage/scripts/PKG_BASE/spkg-requirements.txt --- build/bin/sage-dist-helpers | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/build/bin/sage-dist-helpers b/build/bin/sage-dist-helpers index 567168b1f67..73119347438 100644 --- a/build/bin/sage-dist-helpers +++ b/build/bin/sage-dist-helpers @@ -321,7 +321,15 @@ sdh_store_wheel() { mkdir -p "${SAGE_DESTDIR}${SAGE_SPKG_WHEELS}" && \ $sudo mv "$wheel" "${SAGE_DESTDIR}${SAGE_SPKG_WHEELS}/" || \ sdh_die "Error storing $wheel" - wheel="${SAGE_DESTDIR}${SAGE_SPKG_WHEELS}/${wheel##*/}" + wheel="${SAGE_SPKG_WHEELS}/${wheel##*/}" + if [ -n "${SAGE_SPKG_SCRIPTS}" -a -n "${PKG_BASE}" ]; then + wheel_basename="${wheel##*/}" + distname="${wheel_basename%%-*}" + # Record name and wheel file location + mkdir -p ${SAGE_DESTDIR}${SAGE_SPKG_SCRIPTS}/${PKG_BASE} + echo "${distname} @ file://${wheel}" >> ${SAGE_DESTDIR}${SAGE_SPKG_SCRIPTS}/${PKG_BASE}/spkg-requirements.txt + fi + wheel="${SAGE_DESTDIR}${wheel}" } sdh_store_and_pip_install_wheel() { @@ -373,11 +381,6 @@ sdh_store_and_pip_install_wheel() { fi $sudo sage-pip-install $root $pip_options "$wheel" || \ sdh_die "Error installing ${wheel##*/}" - if [ -n "${SAGE_PKG_DIR}" ]; then - # Record name of installed distribution name for uninstallation. - wheel=${wheel##*/} - echo "${wheel%%-*}" >> ${SAGE_PKG_DIR}/spkg-requirements.txt - fi } sdh_pip_uninstall() { From f8b93c7b8ac623c1ecb56f2a739b0aaa4a51966a Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 11 Oct 2023 13:23:02 -0700 Subject: [PATCH 149/216] build/bin/sage-spkg: Remove unused code for packages without spkg-install.in --- build/bin/sage-spkg | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/build/bin/sage-spkg b/build/bin/sage-spkg index 92c920d57cb..d7de39dcb2d 100755 --- a/build/bin/sage-spkg +++ b/build/bin/sage-spkg @@ -567,24 +567,6 @@ for script in $WRAPPED_SCRIPTS; do fi done - -# When there is no spkg-install, assume the "spkg" is a tarball not -# specifically made for Sage. Since we want it to be as easy as -# possible to install such a package, we "guess" spkg-install. -if [ ! -f spkg-install ]; then - echo '#!/usr/bin/env bash' > spkg-install - if [ -x configure ]; then - echo './configure --prefix="$SAGE_INST_LOCAL" && make && $SAGE_SUDO make install' >> spkg-install - elif [ -f setup.py ]; then - echo 'python setup.py install' >> spkg-install - else - echo >&2 "Error: There is no spkg-install script, no setup.py, and no configure" - echo >&2 "script, so I do not know how to install $PKG_SRC." - exit 1 - fi - chmod +x spkg-install -fi - echo "****************************************************" echo "Host system:" uname -a From f5f300bd406a34ed2b28c7a28458e883193abca9 Mon Sep 17 00:00:00 2001 From: "Alex J. Best" Date: Wed, 11 Oct 2023 21:52:45 +0100 Subject: [PATCH 150/216] try some doctests --- .../multi_polynomial_libsingular.pyx | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx b/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx index b4fa67e00ca..9d3f613a5c7 100644 --- a/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx +++ b/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx @@ -4493,6 +4493,27 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): sage: f.lift(I) [1, x2] + Check that we can work over the integers:: + + sage: R. = ZZ[] + sage: I = R.ideal(x2**2 + x1 - 2, x1**2 - 1) + sage: f = I.gen(0) + x2*I.gen(1) + sage: f.lift(I) + [1, x2] + sage: (f+1).lift(I) + Traceback (most recent call last): + ... + ValueError: polynomial is not in the ideal + sage: f.lift(I) + [1, x2] + sage: A. = PolynomialRing(ZZ,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] + + TESTS: Check that :trac:`13714` is fixed:: From 91b0b8371213b2123c88f68ffc490f96dc3c9f3f Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 11 Oct 2023 14:05:58 -0700 Subject: [PATCH 151/216] build/bin/sage-spkg: Adjust to spkg-requirements.txt being installed directly --- build/bin/sage-spkg | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/build/bin/sage-spkg b/build/bin/sage-spkg index d7de39dcb2d..b540c8e866f 100755 --- a/build/bin/sage-spkg +++ b/build/bin/sage-spkg @@ -704,9 +704,7 @@ unset SAGE_DESTDIR_LOCAL # removed by sage-spkg-uninstall INSTALLED_SCRIPTS_DEST="$SAGE_SPKG_SCRIPTS/$PKG_BASE" -if [ -f spkg-requirements.txt ]; then - INSTALLED_SCRIPTS="$INSTALLED_SCRIPTS piprm-requirements.txt" -else +if [ ! -f $INSTALLED_SCRIPTS_DEST/spkg-requirements.txt ]; then # No packages to uninstall with pip, so remove the prepared uninstall script rm -f spkg-piprm spkg-piprm.in fi From f91c20b2b20dd52c3bc210d7eb2e0705b91b4a21 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 11 Oct 2023 14:35:47 -0700 Subject: [PATCH 152/216] build/make/Makefile.in (SCRIPT_PACKAGE_templ): Remove script dir before running spkg-install --- build/make/Makefile.in | 1 + 1 file changed, 1 insertion(+) diff --git a/build/make/Makefile.in b/build/make/Makefile.in index d6e79c03547..5ded207c435 100644 --- a/build/make/Makefile.in +++ b/build/make/Makefile.in @@ -724,6 +724,7 @@ $(1)-$(4)-no-deps: echo "$$($(4)_DISABLED_MESSAGE)" 2>&1; \ exit 1; \ elif [ -x '$$(SAGE_ROOT)/build/pkgs/$(1)/spkg-install' ]; then \ + rm -rf '$$($(4))/var/lib/sage/scripts/$(1)'; \ cd '$$(SAGE_ROOT)/build/pkgs/$(1)' && \ . '$$(SAGE_ROOT)/src/bin/sage-src-env-config' && \ . '$$(SAGE_ROOT)/src/bin/sage-env-config' && \ From f514e727300182eda06ed6a59fb971c7395312ec Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 19 Sep 2023 16:29:03 -0700 Subject: [PATCH 153/216] sage.symbolic: Remove modules deprecated in #32386 (2021) --- src/sage/symbolic/comparison.py | 13 ------------- src/sage/symbolic/constant.py | 10 ---------- src/sage/symbolic/constants_c.py | 10 ---------- src/sage/symbolic/getitem.py | 12 ------------ src/sage/symbolic/pynac_constant.py | 18 ------------------ src/sage/symbolic/series.py | 10 ---------- src/sage/symbolic/substitution_map.py | 21 --------------------- 7 files changed, 94 deletions(-) delete mode 100644 src/sage/symbolic/comparison.py delete mode 100644 src/sage/symbolic/constant.py delete mode 100644 src/sage/symbolic/constants_c.py delete mode 100644 src/sage/symbolic/getitem.py delete mode 100644 src/sage/symbolic/pynac_constant.py delete mode 100644 src/sage/symbolic/series.py delete mode 100644 src/sage/symbolic/substitution_map.py diff --git a/src/sage/symbolic/comparison.py b/src/sage/symbolic/comparison.py deleted file mode 100644 index 38c23b97d6c..00000000000 --- a/src/sage/symbolic/comparison.py +++ /dev/null @@ -1,13 +0,0 @@ -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', - 'math_sorted', 'mixed_order', '_mixed_key', 'mixed_sorted'], - deprecation=32386) diff --git a/src/sage/symbolic/constant.py b/src/sage/symbolic/constant.py deleted file mode 100644 index 53571b8beb0..00000000000 --- a/src/sage/symbolic/constant.py +++ /dev/null @@ -1,10 +0,0 @@ -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 deleted file mode 100644 index b18d0d0eb2f..00000000000 --- a/src/sage/symbolic/constants_c.py +++ /dev/null @@ -1,10 +0,0 @@ -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 deleted file mode 100644 index 3ff5e400fba..00000000000 --- a/src/sage/symbolic/getitem.py +++ /dev/null @@ -1,12 +0,0 @@ -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'], - deprecation=32386) diff --git a/src/sage/symbolic/pynac_constant.py b/src/sage/symbolic/pynac_constant.py deleted file mode 100644 index 080cc7637be..00000000000 --- a/src/sage/symbolic/pynac_constant.py +++ /dev/null @@ -1,18 +0,0 @@ -""" -Wrapper around Pynac's constants -""" - -# **************************************************************************** -# Copyright (C) 2008 William Stein -# Copyright (C) 2008 Burcin Erocal -# Copyright (C) 2009 Mike Hansen -# -# 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.misc.lazy_import import lazy_import -lazy_import('sage.symbolic.expression', 'PynacConstant', deprecation=32386) diff --git a/src/sage/symbolic/series.py b/src/sage/symbolic/series.py deleted file mode 100644 index 943631c52f2..00000000000 --- a/src/sage/symbolic/series.py +++ /dev/null @@ -1,10 +0,0 @@ -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) diff --git a/src/sage/symbolic/substitution_map.py b/src/sage/symbolic/substitution_map.py deleted file mode 100644 index a883d3aecb0..00000000000 --- a/src/sage/symbolic/substitution_map.py +++ /dev/null @@ -1,21 +0,0 @@ -""" -Substitution Maps - -This object wraps Pynac ``exmap`` objects. These encode substitutions -of symbolic expressions. The main use of this module is to hook into -Pynac's ``subs()`` methods and pass a wrapper for the substitution map -back to Python. -""" - -# **************************************************************************** -# Copyright (C) 2013 Volker Braun -# -# 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.misc.lazy_import import lazy_import -lazy_import('sage.symbolic.expression', ('SubstitutionMap', 'make_map'), deprecation=32386) From 2a5bbce58d782e6962d44877d95bf8d50f3e61dc Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 19 Sep 2023 16:32:53 -0700 Subject: [PATCH 154/216] sage.symbolic.callable: Remove function deprecated in #32665 (2021) --- src/sage/symbolic/callable.py | 28 ---------------------------- 1 file changed, 28 deletions(-) diff --git a/src/sage/symbolic/callable.py b/src/sage/symbolic/callable.py index dc093716a34..ba3dd6aee75 100644 --- a/src/sage/symbolic/callable.py +++ b/src/sage/symbolic/callable.py @@ -69,34 +69,6 @@ ###################################################################### # Callable functions ###################################################################### -def is_CallableSymbolicExpressionRing(x): - """ - Return ``True`` if ``x`` is a callable symbolic expression ring. - - INPUT: - - - ``x`` - object - - OUTPUT: bool - - EXAMPLES:: - - sage: from sage.symbolic.callable import is_CallableSymbolicExpressionRing - sage: is_CallableSymbolicExpressionRing(QQ) - doctest:warning... - DeprecationWarning: is_CallableSymbolicExpressionRing is deprecated; - use isinstance(..., sage.rings.abc.CallableSymbolicExpressionRing instead - See https://github.com/sagemath/sage/issues/32665 for details. - False - sage: var('x,y,z') - (x, y, z) - sage: is_CallableSymbolicExpressionRing(CallableSymbolicExpressionRing((x,y,z))) - True - """ - from sage.misc.superseded import deprecation - deprecation(32665, 'is_CallableSymbolicExpressionRing is deprecated; use isinstance(..., sage.rings.abc.CallableSymbolicExpressionRing instead') - return isinstance(x, CallableSymbolicExpressionRing_class) - def is_CallableSymbolicExpression(x): r""" From ff06d30599d988d4d5a97b4f93a1b2e5e73faea7 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 19 Sep 2023 16:33:31 -0700 Subject: [PATCH 155/216] sage.symbolic.callable: Remove function deprecated in #34215 (2022) --- src/sage/symbolic/callable.py | 29 ----------------------------- 1 file changed, 29 deletions(-) diff --git a/src/sage/symbolic/callable.py b/src/sage/symbolic/callable.py index ba3dd6aee75..6db7f38745d 100644 --- a/src/sage/symbolic/callable.py +++ b/src/sage/symbolic/callable.py @@ -70,35 +70,6 @@ # Callable functions ###################################################################### -def is_CallableSymbolicExpression(x): - r""" - Return ``True`` if ``x`` is a callable symbolic expression. - - EXAMPLES:: - - sage: from sage.symbolic.callable import is_CallableSymbolicExpression - sage: var('a x y z') - (a, x, y, z) - sage: f(x,y) = a + 2*x + 3*y + z - sage: is_CallableSymbolicExpression(f) - doctest:warning... - DeprecationWarning: is_CallableSymbolicExpression is deprecated; - use isinstance(..., Expression) and ....is_callable() instead - See https://github.com/sagemath/sage/issues/34215 for details. - True - sage: is_CallableSymbolicExpression(a+2*x) - False - sage: def foo(n): return n^2 - ... - sage: is_CallableSymbolicExpression(foo) - False - """ - from sage.misc.superseded import deprecation - deprecation(34215, 'is_CallableSymbolicExpression is deprecated; use isinstance(..., Expression) and ....is_callable() instead') - from sage.structure.element import Expression - return isinstance(x, Expression) and isinstance(x.parent(), CallableSymbolicExpressionRing_class) - - class CallableSymbolicExpressionFunctor(ConstructionFunctor): def __init__(self, arguments): """ From cdfbdca403062bcea2753a6114d295abfd7d7c47 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 19 Sep 2023 16:35:30 -0700 Subject: [PATCH 156/216] sage.symbolic.expression: Remove function deprecated in #32638 (2021) --- src/sage/symbolic/expression.pyx | 26 -------------------------- 1 file changed, 26 deletions(-) diff --git a/src/sage/symbolic/expression.pyx b/src/sage/symbolic/expression.pyx index 0f251ac4e5c..b02c17c7604 100644 --- a/src/sage/symbolic/expression.pyx +++ b/src/sage/symbolic/expression.pyx @@ -409,32 +409,6 @@ include "pynac_impl.pxi" from sage.symbolic.symbols import symbol_table, register_symbol # used to be defined in pynac_impl -cpdef bint is_Expression(x): - """ - Return True if ``x`` is a symbolic expression. - - This method is deprecated. Use :func:`isinstance` with - :class:`sage.structure.element.Expression` instead. - - EXAMPLES:: - - sage: from sage.symbolic.expression import is_Expression - sage: is_Expression(x) - doctest:warning... - DeprecationWarning: is_Expression is deprecated; - use isinstance(..., sage.structure.element.Expression) instead - See https://github.com/sagemath/sage/issues/32638 for details. - True - sage: is_Expression(2) - False - sage: is_Expression(SR(2)) - True - """ - from sage.misc.superseded import deprecation - deprecation(32638, 'is_Expression is deprecated; use isinstance(..., sage.structure.element.Expression) instead') - return isinstance(x, Expression) - - cpdef bint is_SymbolicEquation(x): """ Return True if *x* is a symbolic equation. From 6078d3866b8757059f38889ab15aef7ac081e168 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 19 Sep 2023 16:38:07 -0700 Subject: [PATCH 157/216] sage.symbolic.all: Remove import of sage.symbolic.constants.I, deprecated in #18036 (2020) --- src/sage/symbolic/all.py | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/sage/symbolic/all.py b/src/sage/symbolic/all.py index 399ab56e78c..b5a0883d202 100644 --- a/src/sage/symbolic/all.py +++ b/src/sage/symbolic/all.py @@ -1,10 +1,3 @@ -from sage.misc.lazy_import import lazy_import - -lazy_import("sage.symbolic.constants", "I", deprecation=(18036, - "import I from sage.symbolic.constants for the imaginary unit viewed as an element of SR, or from sage.rings.imaginary_unit for the element of ZZ[i]")) -lazy_import("sage.symbolic.constants", "I", as_="i", deprecation=(18036, - "import I from sage.symbolic.constants for the imaginary unit viewed as an element of SR, or from sage.rings.imaginary_unit for the element of ZZ[i]")) - from .ring import SR from .constants import (pi, e, NaN, golden_ratio, log2, euler_gamma, catalan, khinchin, twinprime, mertens, glaisher) From 26007d5c25ae77e5b0dbf6a68a5f8e9b36476b0a Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 19 Sep 2023 16:39:22 -0700 Subject: [PATCH 158/216] sage.symbolic.ring: Remove function deprecated in #32665 (2021) --- src/sage/symbolic/ring.pyx | 27 --------------------------- 1 file changed, 27 deletions(-) diff --git a/src/sage/symbolic/ring.pyx b/src/sage/symbolic/ring.pyx index d45b88e24de..822eaacd30b 100644 --- a/src/sage/symbolic/ring.pyx +++ b/src/sage/symbolic/ring.pyx @@ -1301,33 +1301,6 @@ def the_SymbolicRing(): return SR -def is_SymbolicExpressionRing(R): - """ - Return True if ``R`` is the symbolic expression ring. - - This function is deprecated. Instead, either use ``R is SR`` (to - test whether ``R`` is the unique symbolic ring ``SR``); or - ``isinstance`` with :class:`~sage.rings.abc.SymbolicRing` - (when also symbolic subrings and callable symbolic rings should - be accepted). - - EXAMPLES:: - - sage: from sage.symbolic.ring import is_SymbolicExpressionRing - sage: is_SymbolicExpressionRing(ZZ) - doctest:warning... - DeprecationWarning: is_SymbolicExpressionRing is deprecated; - use "... is SR" or isinstance(..., sage.rings.abc.SymbolicRing instead - See https://github.com/sagemath/sage/issues/32665 for details. - False - sage: is_SymbolicExpressionRing(SR) - True - """ - from sage.misc.superseded import deprecation - 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:: From 764499d17917915bf776c34655518053bf4fe1f2 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 19 Sep 2023 16:42:01 -0700 Subject: [PATCH 159/216] sage.symbolic.expression: Remove method deprecated in #29738 (2021) --- src/sage/symbolic/expression.pyx | 26 -------------------------- 1 file changed, 26 deletions(-) diff --git a/src/sage/symbolic/expression.pyx b/src/sage/symbolic/expression.pyx index b02c17c7604..b0f7b22e09e 100644 --- a/src/sage/symbolic/expression.pyx +++ b/src/sage/symbolic/expression.pyx @@ -6320,32 +6320,6 @@ cdef class Expression(Expression_abc): nops = number_of_operands - def __len__(self): - """ - Return the number of operands of this expression. - - This is deprecated; use :meth:`number_of_operands` instead. - - EXAMPLES:: - - sage: var('a,b,c,x,y') - (a, b, c, x, y) - sage: len(a) - doctest:warning... - DeprecationWarning: using len on a symbolic expression is deprecated; use method number_of_operands instead - See https://github.com/sagemath/sage/issues/29738 for details. - 0 - sage: len((a^2 + b^2 + (x+y)^2)) - 3 - sage: len((a^2)) - 2 - sage: len(a*b^2*c) - 3 - """ - from sage.misc.superseded import deprecation - deprecation(29738, "using len on a symbolic expression is deprecated; use method number_of_operands instead") - return self.number_of_operands() - def _unpack_operands(self): """ Unpack the operands of this expression converting each to a Python From d0ab75c2ffa53ad0ed8146ba69f7e1e145456069 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 19 Sep 2023 18:00:28 -0700 Subject: [PATCH 160/216] src/sage/symbolic/expression.pxd: Update --- src/sage/symbolic/expression.pxd | 1 - 1 file changed, 1 deletion(-) diff --git a/src/sage/symbolic/expression.pxd b/src/sage/symbolic/expression.pxd index 1fa578d43c3..33e352b7f3d 100644 --- a/src/sage/symbolic/expression.pxd +++ b/src/sage/symbolic/expression.pxd @@ -1,4 +1,3 @@ -cpdef bint is_Expression(x) cpdef _repr_Expression(x) cpdef _latex_Expression(x) cpdef new_Expression(parent, x) From 8632f17cd06cfe6c254b91cebda6e9d1fc8105ca Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 20 Sep 2023 10:12:17 -0700 Subject: [PATCH 161/216] src/sage/combinat/words/alphabet.py: Check type before calling len --- src/sage/combinat/words/alphabet.py | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/sage/combinat/words/alphabet.py b/src/sage/combinat/words/alphabet.py index 5d1b0d5468a..3289ad5aa1a 100644 --- a/src/sage/combinat/words/alphabet.py +++ b/src/sage/combinat/words/alphabet.py @@ -32,15 +32,14 @@ # http://www.gnu.org/licenses/ # **************************************************************************** -from sage.categories.sets_cat import Sets +import collections.abc -from sage.sets.totally_ordered_finite_set import TotallyOrderedFiniteSet -from sage.sets.family import Family - -from sage.rings.integer import Integer +from sage.categories.sets_cat import Sets from sage.rings.infinity import Infinity - +from sage.rings.integer import Integer +from sage.sets.family import Family from sage.sets.non_negative_integers import NonNegativeIntegers +from sage.sets.totally_ordered_finite_set import TotallyOrderedFiniteSet set_of_letters = { @@ -222,7 +221,7 @@ def build_alphabet(data=None, names=None, name=None): return IntegerRange(Integer(data)) if isinstance(names, str): return TotallyOrderedFiniteSet([names + '%d' % i for i in range(data)]) - if len(names) == data: + if isinstance(names, collections.abc.Sequence) and len(names) == data: return TotallyOrderedFiniteSet(names) raise ValueError("invalid value for names") From bc242a2bd8d9f784076151b2a5e96ed666ea9758 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 11 Oct 2023 14:40:05 -0700 Subject: [PATCH 162/216] src/doc/en/reference/calculus/index.rst: Remove removed module --- src/doc/en/reference/calculus/index.rst | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/doc/en/reference/calculus/index.rst b/src/doc/en/reference/calculus/index.rst index abbb408f6e9..c9a5158e522 100644 --- a/src/doc/en/reference/calculus/index.rst +++ b/src/doc/en/reference/calculus/index.rst @@ -53,7 +53,6 @@ Internal functionality supporting calculus - :doc:`sage/symbolic/function_factory` - :doc:`Internals of Callable Symbolic Expressions ` - :doc:`sage/symbolic/expression_conversions` -- :doc:`sage/symbolic/substitution_map` - :doc:`sage/symbolic/benchmark` - :doc:`sage/symbolic/random_tests` - :doc:`sage/symbolic/maxima_wrapper` @@ -95,7 +94,6 @@ Internal functionality supporting calculus sage/calculus/var sage/symbolic/maxima_wrapper sage/symbolic/operators - sage/symbolic/substitution_map sage/symbolic/benchmark sage/symbolic/random_tests From 0aaf02e55702c32411e329b3964fd02447ff7c37 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 11 Oct 2023 15:29:47 -0700 Subject: [PATCH 163/216] build/make/Makefile.in (SCRIPT_PACKAGE_templ) [SAGE_CHECK=yes]: Call script spkg-postinstcheck if it exists; new target SPKG-check --- build/make/Makefile.in | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/build/make/Makefile.in b/build/make/Makefile.in index 5ded207c435..60d40f8991e 100644 --- a/build/make/Makefile.in +++ b/build/make/Makefile.in @@ -737,7 +737,8 @@ $(1)-$(4)-no-deps: SAGE_SPKG_WHEELS=$$($(4))/var/lib/sage/wheels \ SAGE_SPKG_SCRIPTS=$$($(4))/var/lib/sage/scripts \ SAGE_INST_LOCAL=$$($(4)) \ - sage-logger -p 'SAGE_CHECK=$$(SAGE_CHECK_$(1)) $$(SAGE_ROOT)/build/pkgs/$(1)/spkg-install' '$$(SAGE_LOGS)/$(1)-$(2).log' && \ + SAGE_CHECK=$$(SAGE_CHECK_$(1)) \ + sage-logger -p '$$(SAGE_ROOT)/build/pkgs/$(1)/spkg-install && if [ $$$$SAGE_CHECK != no -a -x $$(SAGE_ROOT)/build/pkgs/$(1)/spkg-postinstcheck ]; then $$(SAGE_ROOT)/build/pkgs/$(1)/spkg-postinstcheck; fi' '$$(SAGE_LOGS)/$(1)-$(2).log' && \ rm -f "$$($(4))/$(SPKG_INST_RELDIR)/$(1)"-* && \ touch "$$($(4))/$(SPKG_INST_RELDIR)/$(1)-$(2)"; \ else ( \ @@ -757,6 +758,26 @@ $(1)-$(4)-no-deps: $(1)-no-deps: $(1)-$(4)-no-deps +$(1)-$(4)-check: + $(PLUS)@if [ -x $$(SAGE_ROOT)/build/pkgs/$(1)/spkg-postinstcheck ]; then \ + cd '$$(SAGE_ROOT)/build/pkgs/$(1)' && \ + . '$$(SAGE_ROOT)/src/bin/sage-src-env-config' && \ + . '$$(SAGE_ROOT)/src/bin/sage-env-config' && \ + . '$$(SAGE_ROOT)/src/bin/sage-env' && \ + . '$$(SAGE_ROOT)/build/bin/sage-build-env-config' && \ + . '$$(SAGE_ROOT)/build/bin/sage-build-env' && \ + PKG_BASE="$(1)" \ + PKG_VER="$(2)" \ + PKG_NAME="$(1)-$(2)" \ + SAGE_SPKG_WHEELS=$$($(4))/var/lib/sage/wheels \ + SAGE_SPKG_SCRIPTS=$$($(4))/var/lib/sage/scripts \ + SAGE_INST_LOCAL=$$($(4)) \ + SAGE_CHECK=$$(SAGE_CHECK_$(1)) \ + sage-logger -p '$$(SAGE_ROOT)/build/pkgs/$(1)/spkg-postinstcheck' '$$(SAGE_LOGS)/$(1)-$(2).log'; \ + fi + +$(1)-check: $(1)-$(4)-check + $(1)-$(4)-uninstall: -$(AM_V_at)cd '$$(SAGE_ROOT)/build/pkgs/$(1)' && \ . '$$(SAGE_ROOT)/src/bin/sage-src-env-config' && \ From 417de39f72e245b3f921d19d278ea37d00e6dc59 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 11 Oct 2023 15:30:58 -0700 Subject: [PATCH 164/216] build/pkgs/sagemath_*/spkg-postinstcheck: Break out from spkg-install --- .../sagemath_categories/spkg-postinstcheck | 1 + .../sagemath_environment/spkg-postinstcheck | 1 + build/pkgs/sagemath_objects/spkg-install | 23 ---------------- .../pkgs/sagemath_objects/spkg-postinstcheck | 27 +++++++++++++++++++ build/pkgs/sagemath_repl/spkg-postinstcheck | 1 + 5 files changed, 30 insertions(+), 23 deletions(-) create mode 120000 build/pkgs/sagemath_categories/spkg-postinstcheck create mode 120000 build/pkgs/sagemath_environment/spkg-postinstcheck create mode 100755 build/pkgs/sagemath_objects/spkg-postinstcheck create mode 120000 build/pkgs/sagemath_repl/spkg-postinstcheck diff --git a/build/pkgs/sagemath_categories/spkg-postinstcheck b/build/pkgs/sagemath_categories/spkg-postinstcheck new file mode 120000 index 00000000000..313e9f9dc98 --- /dev/null +++ b/build/pkgs/sagemath_categories/spkg-postinstcheck @@ -0,0 +1 @@ +../sagemath_objects/spkg-postinstcheck \ No newline at end of file diff --git a/build/pkgs/sagemath_environment/spkg-postinstcheck b/build/pkgs/sagemath_environment/spkg-postinstcheck new file mode 120000 index 00000000000..313e9f9dc98 --- /dev/null +++ b/build/pkgs/sagemath_environment/spkg-postinstcheck @@ -0,0 +1 @@ +../sagemath_objects/spkg-postinstcheck \ No newline at end of file diff --git a/build/pkgs/sagemath_objects/spkg-install b/build/pkgs/sagemath_objects/spkg-install index 472e7f0d4d6..18ceb18724d 100755 --- a/build/pkgs/sagemath_objects/spkg-install +++ b/build/pkgs/sagemath_objects/spkg-install @@ -23,26 +23,3 @@ python3 -m build --outdir "$DIST_DIR"/dist . || sdh_die "Failure building sdist wheel=$(cd "$DIST_DIR" && sdh_store_wheel . >&2 && echo $wheel) ls -l "$wheel" - -if [ "$SAGE_CHECK" != no ]; then - export TOX_PARALLEL_NO_SPINNER=1 - echo Running "tox -r -p auto -v --installpkg $wheel" - tox -r -p auto -v --installpkg $wheel - status=$? - case $status:$SAGE_CHECK:$([ -r known-test-failures.json ]; echo $?) in - 0:*:0) echo "Passed the test suite (modulo baseline known-test-failures*.json)";; - 0:*:*) echo "Passed the test suite";; - *:warn:0) echo "Warning: New failures (not in baseline known-test-failures*.json (ignored)"; status=0;; - *:warn:*) echo "Warning: Failures testing the package (ignored)"; status=0;; - *:yes:0) echo "New failures, not in baseline known-test-failures*.json";; - *:yes:*) echo "Failures testing the package";; - esac - # Show summaries of failures (suppress lines ending with '[failed in baseline]') - for f in $(pwd)/.tox/sagepython-sagewheels-nopypi-norequirements*/log/*-command*.log; do - if [ -r "$f" ]; then - echo "$f" - grep '^sage -t.*#[^]]*$' "$f" - fi - done - exit $status -fi diff --git a/build/pkgs/sagemath_objects/spkg-postinstcheck b/build/pkgs/sagemath_objects/spkg-postinstcheck new file mode 100755 index 00000000000..87cea0fc38f --- /dev/null +++ b/build/pkgs/sagemath_objects/spkg-postinstcheck @@ -0,0 +1,27 @@ +#!/usr/bin/env bash +cd src + +export PIP_NO_INDEX=true +export PIP_FIND_LINKS="file://$SAGE_SPKG_WHEELS" + +export TOX_PARALLEL_NO_SPINNER=1 +wheel="$(sed -n '1s,.*@ file://,,p' $SAGE_SPKG_SCRIPTS/$PKG_BASE/spkg-requirements.txt)" +echo Running "tox -r -p auto -v --installpkg $wheel" +tox -r -p auto -v --installpkg "$wheel" +status=$? +case $status:$SAGE_CHECK:$([ -r known-test-failures.json ]; echo $?) in + 0:*:0) echo "Passed the test suite (modulo baseline known-test-failures*.json)";; + 0:*:*) echo "Passed the test suite";; + *:warn:0) echo "Warning: New failures (not in baseline known-test-failures*.json (ignored)"; status=0;; + *:warn:*) echo "Warning: Failures testing the package (ignored)"; status=0;; + *:yes:0) echo "New failures, not in baseline known-test-failures*.json";; + *:yes:*) echo "Failures testing the package";; +esac +# Show summaries of failures (suppress lines ending with '[failed in baseline]') +for f in $(pwd)/.tox/sagepython-sagewheels-nopypi-norequirements*/log/*-command*.log; do + if [ -r "$f" ]; then + echo "$f" + grep '^sage -t.*#[^]]*$' "$f" + fi +done +exit $status diff --git a/build/pkgs/sagemath_repl/spkg-postinstcheck b/build/pkgs/sagemath_repl/spkg-postinstcheck new file mode 120000 index 00000000000..313e9f9dc98 --- /dev/null +++ b/build/pkgs/sagemath_repl/spkg-postinstcheck @@ -0,0 +1 @@ +../sagemath_objects/spkg-postinstcheck \ No newline at end of file From 3c2939ab3efea15f2609e9444b6f85cb5ba9215c Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 11 Oct 2023 15:52:17 -0700 Subject: [PATCH 165/216] Rename spkg-postinstcheck -> spkg-check --- build/make/Makefile.in | 6 +++--- build/pkgs/sagemath_categories/spkg-check | 1 + build/pkgs/sagemath_categories/spkg-postinstcheck | 1 - build/pkgs/sagemath_environment/spkg-check | 1 + build/pkgs/sagemath_environment/spkg-postinstcheck | 1 - .../sagemath_objects/{spkg-postinstcheck => spkg-check} | 0 build/pkgs/sagemath_repl/spkg-check | 1 + build/pkgs/sagemath_repl/spkg-postinstcheck | 1 - 8 files changed, 6 insertions(+), 6 deletions(-) create mode 120000 build/pkgs/sagemath_categories/spkg-check delete mode 120000 build/pkgs/sagemath_categories/spkg-postinstcheck create mode 120000 build/pkgs/sagemath_environment/spkg-check delete mode 120000 build/pkgs/sagemath_environment/spkg-postinstcheck rename build/pkgs/sagemath_objects/{spkg-postinstcheck => spkg-check} (100%) create mode 120000 build/pkgs/sagemath_repl/spkg-check delete mode 120000 build/pkgs/sagemath_repl/spkg-postinstcheck diff --git a/build/make/Makefile.in b/build/make/Makefile.in index 60d40f8991e..6a1d202bff9 100644 --- a/build/make/Makefile.in +++ b/build/make/Makefile.in @@ -738,7 +738,7 @@ $(1)-$(4)-no-deps: SAGE_SPKG_SCRIPTS=$$($(4))/var/lib/sage/scripts \ SAGE_INST_LOCAL=$$($(4)) \ SAGE_CHECK=$$(SAGE_CHECK_$(1)) \ - sage-logger -p '$$(SAGE_ROOT)/build/pkgs/$(1)/spkg-install && if [ $$$$SAGE_CHECK != no -a -x $$(SAGE_ROOT)/build/pkgs/$(1)/spkg-postinstcheck ]; then $$(SAGE_ROOT)/build/pkgs/$(1)/spkg-postinstcheck; fi' '$$(SAGE_LOGS)/$(1)-$(2).log' && \ + sage-logger -p '$$(SAGE_ROOT)/build/pkgs/$(1)/spkg-install && if [ $$$$SAGE_CHECK != no -a -x $$(SAGE_ROOT)/build/pkgs/$(1)/spkg-check ]; then $$(SAGE_ROOT)/build/pkgs/$(1)/spkg-check; fi' '$$(SAGE_LOGS)/$(1)-$(2).log' && \ rm -f "$$($(4))/$(SPKG_INST_RELDIR)/$(1)"-* && \ touch "$$($(4))/$(SPKG_INST_RELDIR)/$(1)-$(2)"; \ else ( \ @@ -759,7 +759,7 @@ $(1)-$(4)-no-deps: $(1)-no-deps: $(1)-$(4)-no-deps $(1)-$(4)-check: - $(PLUS)@if [ -x $$(SAGE_ROOT)/build/pkgs/$(1)/spkg-postinstcheck ]; then \ + $(PLUS)@if [ -x $$(SAGE_ROOT)/build/pkgs/$(1)/spkg-check ]; then \ cd '$$(SAGE_ROOT)/build/pkgs/$(1)' && \ . '$$(SAGE_ROOT)/src/bin/sage-src-env-config' && \ . '$$(SAGE_ROOT)/src/bin/sage-env-config' && \ @@ -773,7 +773,7 @@ $(1)-$(4)-check: SAGE_SPKG_SCRIPTS=$$($(4))/var/lib/sage/scripts \ SAGE_INST_LOCAL=$$($(4)) \ SAGE_CHECK=$$(SAGE_CHECK_$(1)) \ - sage-logger -p '$$(SAGE_ROOT)/build/pkgs/$(1)/spkg-postinstcheck' '$$(SAGE_LOGS)/$(1)-$(2).log'; \ + sage-logger -p '$$(SAGE_ROOT)/build/pkgs/$(1)/spkg-check' '$$(SAGE_LOGS)/$(1)-$(2).log'; \ fi $(1)-check: $(1)-$(4)-check diff --git a/build/pkgs/sagemath_categories/spkg-check b/build/pkgs/sagemath_categories/spkg-check new file mode 120000 index 00000000000..91c6b1835fc --- /dev/null +++ b/build/pkgs/sagemath_categories/spkg-check @@ -0,0 +1 @@ +../sagemath_objects/spkg-check \ No newline at end of file diff --git a/build/pkgs/sagemath_categories/spkg-postinstcheck b/build/pkgs/sagemath_categories/spkg-postinstcheck deleted file mode 120000 index 313e9f9dc98..00000000000 --- a/build/pkgs/sagemath_categories/spkg-postinstcheck +++ /dev/null @@ -1 +0,0 @@ -../sagemath_objects/spkg-postinstcheck \ No newline at end of file diff --git a/build/pkgs/sagemath_environment/spkg-check b/build/pkgs/sagemath_environment/spkg-check new file mode 120000 index 00000000000..91c6b1835fc --- /dev/null +++ b/build/pkgs/sagemath_environment/spkg-check @@ -0,0 +1 @@ +../sagemath_objects/spkg-check \ No newline at end of file diff --git a/build/pkgs/sagemath_environment/spkg-postinstcheck b/build/pkgs/sagemath_environment/spkg-postinstcheck deleted file mode 120000 index 313e9f9dc98..00000000000 --- a/build/pkgs/sagemath_environment/spkg-postinstcheck +++ /dev/null @@ -1 +0,0 @@ -../sagemath_objects/spkg-postinstcheck \ No newline at end of file diff --git a/build/pkgs/sagemath_objects/spkg-postinstcheck b/build/pkgs/sagemath_objects/spkg-check similarity index 100% rename from build/pkgs/sagemath_objects/spkg-postinstcheck rename to build/pkgs/sagemath_objects/spkg-check diff --git a/build/pkgs/sagemath_repl/spkg-check b/build/pkgs/sagemath_repl/spkg-check new file mode 120000 index 00000000000..91c6b1835fc --- /dev/null +++ b/build/pkgs/sagemath_repl/spkg-check @@ -0,0 +1 @@ +../sagemath_objects/spkg-check \ No newline at end of file diff --git a/build/pkgs/sagemath_repl/spkg-postinstcheck b/build/pkgs/sagemath_repl/spkg-postinstcheck deleted file mode 120000 index 313e9f9dc98..00000000000 --- a/build/pkgs/sagemath_repl/spkg-postinstcheck +++ /dev/null @@ -1 +0,0 @@ -../sagemath_objects/spkg-postinstcheck \ No newline at end of file From af6d0ad8559a5b926ec9fa99bf4400294cef227d Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 11 Oct 2023 16:24:08 -0700 Subject: [PATCH 166/216] build/pkgs/sage_sws2rst/spkg-install: Do not call spkg-check from here any more --- build/pkgs/sage_sws2rst/spkg-check | 11 ++++++++++- build/pkgs/sage_sws2rst/spkg-install | 10 ---------- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/build/pkgs/sage_sws2rst/spkg-check b/build/pkgs/sage_sws2rst/spkg-check index 667df773214..7372750871e 100755 --- a/build/pkgs/sage_sws2rst/spkg-check +++ b/build/pkgs/sage_sws2rst/spkg-check @@ -1,2 +1,11 @@ #! /bin/sh -cd src && ./check.sh +cd src +./check.sh +if [ $? -ne 0 ]; then + if [ "$SAGE_CHECK" = "warn" ]; then + echo >&2 "Warning: Failures testing package $PKG_NAME (ignored)" + else + echo >&2 "Error testing package $PKG_NAME" + exit 1 + fi +fi diff --git a/build/pkgs/sage_sws2rst/spkg-install b/build/pkgs/sage_sws2rst/spkg-install index 9cb71471fd8..a180fb36542 100755 --- a/build/pkgs/sage_sws2rst/spkg-install +++ b/build/pkgs/sage_sws2rst/spkg-install @@ -18,13 +18,3 @@ if [ "$SAGE_EDITABLE" = yes ]; then else sdh_pip_install . fi -cd .. -# For type=script packages, spkg-check is not run -case "$SAGE_CHECK" in - yes) - ./spkg-check - ;; - warn) - ./spkg-check || echo >&2 "Warning: Failures testing package sage_sws2rst (ignored)" - ;; -esac From 22b101f6473209959d7eb81243aebec573152c17 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 11 Oct 2023 17:25:52 -0700 Subject: [PATCH 167/216] build/make/Makefile.in (pypi-wheels-check): New target --- build/make/Makefile.in | 2 ++ 1 file changed, 2 insertions(+) diff --git a/build/make/Makefile.in b/build/make/Makefile.in index 6a1d202bff9..6031ae7fa2a 100644 --- a/build/make/Makefile.in +++ b/build/make/Makefile.in @@ -468,6 +468,8 @@ wheels: $(MAKE_REC) SAGE_EDITABLE=no SAGE_WHEELS=yes $(WHEEL_PACKAGES) @echo "Built wheels are in venv/var/lib/sage/wheels/" +pypi-wheels-check: $(PYPI_WHEEL_PACKAGES:%=%-check) + #============================================================================== # Setting SAGE_CHECK... variables #============================================================================== From 383861343e434e569a051dd16545ada948554ff9 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 11 Oct 2023 18:12:23 -0700 Subject: [PATCH 168/216] .github/workflows/build.yml: Separate build and test --- .github/workflows/build.yml | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 062fa973ac3..8a44a1ff188 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -107,20 +107,19 @@ jobs: (cd worktree-image && git commit -q -m "current changes" --allow-empty -a && git am; git reset --quiet old; git add -N .) < upstream/ci_fixes.patch fi - - name: Incremental build, test changed files (sage -t --new) + - name: Incremental build id: incremental run: | # Now re-bootstrap and build. The build is incremental because we were careful with the timestamps. - # We run tests with "sage -t --new"; this only tests the uncommitted changes. - ./bootstrap && make build && ./sage -t --new -p2 + ./bootstrap && make build working-directory: ./worktree-image env: MAKE: make -j2 --output-sync=recurse SAGE_NUM_THREADS: 2 - - name: Build and test modularized distributions + - name: Build modularized distributions if: always() && steps.worktree.outcome == 'success' - run: make V=0 tox && make pypi-wheels + run: make V=0 tox && make SAGE_CHECK=no pypi-wheels working-directory: ./worktree-image env: MAKE: make -j2 --output-sync=recurse @@ -165,6 +164,25 @@ jobs: MAKE: make -j2 --output-sync=recurse SAGE_NUM_THREADS: 2 + # Testing + + - name: Test changed files (sage -t --new) + run: | + # We run tests with "sage -t --new"; this only tests the uncommitted changes. + ./sage -t --new -p2 + working-directory: ./worktree-image + env: + MAKE: make -j2 --output-sync=recurse + SAGE_NUM_THREADS: 2 + + - name: Test modularized distributions + if: always() && steps.worktree.outcome == 'success' + run: make V=0 tox && make pypi-wheels-check + working-directory: ./worktree-image + env: + MAKE: make -j2 --output-sync=recurse + SAGE_NUM_THREADS: 2 + - name: Pytest if: contains(github.ref, 'pytest') run: | From c7805237c35dbcbea0842da259784e925b0922fd Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 11 Oct 2023 19:18:05 -0700 Subject: [PATCH 169/216] flit_core vendors its own tomli, so remove tomli from build deps --- build/pkgs/backcall/dependencies | 2 +- build/pkgs/entrypoints/dependencies | 2 +- build/pkgs/pyparsing/dependencies | 2 +- build/pkgs/tomli/spkg-install.in | 7 +------ 4 files changed, 4 insertions(+), 9 deletions(-) diff --git a/build/pkgs/backcall/dependencies b/build/pkgs/backcall/dependencies index 4fedbe70cd1..f863a25db11 100644 --- a/build/pkgs/backcall/dependencies +++ b/build/pkgs/backcall/dependencies @@ -1,4 +1,4 @@ - | $(PYTHON_TOOLCHAIN) flit_core tomli $(PYTHON) + | $(PYTHON_TOOLCHAIN) flit_core $(PYTHON) ---------- All lines of this file are ignored except the first. diff --git a/build/pkgs/entrypoints/dependencies b/build/pkgs/entrypoints/dependencies index 4fedbe70cd1..f863a25db11 100644 --- a/build/pkgs/entrypoints/dependencies +++ b/build/pkgs/entrypoints/dependencies @@ -1,4 +1,4 @@ - | $(PYTHON_TOOLCHAIN) flit_core tomli $(PYTHON) + | $(PYTHON_TOOLCHAIN) flit_core $(PYTHON) ---------- All lines of this file are ignored except the first. diff --git a/build/pkgs/pyparsing/dependencies b/build/pkgs/pyparsing/dependencies index 22915b3da68..287adef3710 100644 --- a/build/pkgs/pyparsing/dependencies +++ b/build/pkgs/pyparsing/dependencies @@ -1,4 +1,4 @@ - | pip wheel flit_core tomli $(PYTHON) + | pip wheel flit_core $(PYTHON) ---------- All lines of this file are ignored except the first. diff --git a/build/pkgs/tomli/spkg-install.in b/build/pkgs/tomli/spkg-install.in index e0d72afde3b..37ac1a53437 100644 --- a/build/pkgs/tomli/spkg-install.in +++ b/build/pkgs/tomli/spkg-install.in @@ -1,7 +1,2 @@ cd src -# tomli's build system, flit_core, has a runtime dependency on tomli. -# Hence we make the uninstalled tomli sources available during the installation -# and disable build isolation -- which would require a tomli wheel to -# be available for setting up the build environment. -export PYTHONPATH="$(pwd)" -sdh_pip_install --no-build-isolation . +sdh_pip_install . From 8224cb097fcbeecb4f19ef42bec85eeef0d1a33a Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 11 Oct 2023 22:36:09 -0700 Subject: [PATCH 170/216] .github/workflows/build.yml: Fix 'if' of some steps --- .github/workflows/build.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 8a44a1ff188..1d365405f2a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -167,6 +167,7 @@ jobs: # Testing - name: Test changed files (sage -t --new) + if: always() && steps.build.outcome == 'success' run: | # We run tests with "sage -t --new"; this only tests the uncommitted changes. ./sage -t --new -p2 @@ -176,7 +177,7 @@ jobs: SAGE_NUM_THREADS: 2 - name: Test modularized distributions - if: always() && steps.worktree.outcome == 'success' + if: always() && steps.build.outcome == 'success' run: make V=0 tox && make pypi-wheels-check working-directory: ./worktree-image env: From 7f48944e4177d42a8677a2be44650edefbf99c09 Mon Sep 17 00:00:00 2001 From: Sebastian Date: Thu, 12 Oct 2023 08:17:43 +0200 Subject: [PATCH 171/216] 36333: change regarding call of nullity --- src/sage/knots/link.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/sage/knots/link.py b/src/sage/knots/link.py index 224ca683a90..29d9cdd159a 100644 --- a/src/sage/knots/link.py +++ b/src/sage/knots/link.py @@ -3139,10 +3139,11 @@ def is_colorable(self, n=None): .. SEEALSO:: :meth:`colorings` and :meth:`coloring_maps` """ - try: + M = self._coloring_matrix(n=n) + if M.base_ring().is_field(): return self._coloring_matrix(n=n).nullity() > 1 - except NotImplementedError: - M = self._coloring_matrix(n=n) + else: + # nullity is not implemented in this case return M.right_kernel_matrix().dimensions()[0] > 1 def colorings(self, n=None): From e3dce3f4841721316aaa475b4fba5e20fca319b0 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 12 Oct 2023 09:11:39 -0700 Subject: [PATCH 172/216] conda: Do not pin setuptools, instead add legacy editable to install instructions --- .github/workflows/ci-conda.yml | 2 +- build/pkgs/setuptools/distros/conda.txt | 5 +---- src/doc/en/installation/conda.rst | 2 +- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci-conda.yml b/.github/workflows/ci-conda.yml index 75babf3ab8c..2477d39794e 100644 --- a/.github/workflows/ci-conda.yml +++ b/.github/workflows/ci-conda.yml @@ -92,7 +92,7 @@ jobs: run: | # Use --no-deps and pip check below to verify that all necessary dependencies are installed via conda. pip install --no-build-isolation --no-deps -v -v -e ./pkgs/sage-conf ./pkgs/sage-setup - pip install --no-build-isolation --no-deps -v -v -e ./src + pip install --no-build-isolation --no-deps --config-settings editable_mode=compat -v -v -e ./src env: SAGE_NUM_THREADS: 2 diff --git a/build/pkgs/setuptools/distros/conda.txt b/build/pkgs/setuptools/distros/conda.txt index 2602d0f6344..49fe098d9e6 100644 --- a/build/pkgs/setuptools/distros/conda.txt +++ b/build/pkgs/setuptools/distros/conda.txt @@ -1,4 +1 @@ -# Set this bound until https://github.com/sagemath/sage/issues/34209 adds support for PEP660 editable builds -# By setting this version bound, we avoid having to include the following in our installation instructions. -# export SETUPTOOLS_ENABLE_FEATURES=legacy-editable -"setuptools<64" +setuptools diff --git a/src/doc/en/installation/conda.rst b/src/doc/en/installation/conda.rst index 6b4cb871dd7..1b12e2d5057 100644 --- a/src/doc/en/installation/conda.rst +++ b/src/doc/en/installation/conda.rst @@ -158,7 +158,7 @@ suffices to restart Sage. After editing any Cython files, rebuild the Sage library using:: - $ pip install --no-build-isolation -v -v --editable src + $ pip install --no-build-isolation --config-settings editable_mode=compat -v -v --editable src In order to update the conda environment later, you can run:: From c60de9a4944212184d77034baf5a07f37727ee29 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 27 Sep 2023 11:44:56 -0700 Subject: [PATCH 173/216] build/pkgs/setuptools_wheel: Make distros a symlink too --- build/pkgs/setuptools_wheel/distros | 1 + build/pkgs/setuptools_wheel/distros/repology.txt | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) create mode 120000 build/pkgs/setuptools_wheel/distros delete mode 100644 build/pkgs/setuptools_wheel/distros/repology.txt diff --git a/build/pkgs/setuptools_wheel/distros b/build/pkgs/setuptools_wheel/distros new file mode 120000 index 00000000000..b22be5c01a6 --- /dev/null +++ b/build/pkgs/setuptools_wheel/distros @@ -0,0 +1 @@ +../setuptools/distros \ No newline at end of file diff --git a/build/pkgs/setuptools_wheel/distros/repology.txt b/build/pkgs/setuptools_wheel/distros/repology.txt deleted file mode 100644 index 845a263c318..00000000000 --- a/build/pkgs/setuptools_wheel/distros/repology.txt +++ /dev/null @@ -1 +0,0 @@ -python:setuptools From 756e5c431386cba8a23d096330cac7d5bf036f2f Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 11 Oct 2023 09:20:58 -0700 Subject: [PATCH 174/216] src/doc/en/installation/conda.rst: Restore 'bootstrap' in instructions, lost in #36367 --- src/doc/en/installation/conda.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/doc/en/installation/conda.rst b/src/doc/en/installation/conda.rst index 1b12e2d5057..cb2095bdd0b 100644 --- a/src/doc/en/installation/conda.rst +++ b/src/doc/en/installation/conda.rst @@ -134,8 +134,9 @@ Here we assume that you are using a git checkout. installed. You can use the additional option ``python=3.9`` in the above ``env create`` command to select another Python version (here 3.9). - - Install the build prerequisites and the Sage library:: + - Bootstrap the source tree and install the build prerequisites and the Sage library:: + $ ./bootstrap $ pip install --no-build-isolation -v -v --editable ./pkgs/sage-conf_conda ./pkgs/sage-setup $ pip install --no-build-isolation --config-settings editable_mode=compat -v -v --editable ./src From ddbbdc5fb4263681ac7026d6d0b4e5de0bd63c26 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 11 Oct 2023 14:30:32 -0700 Subject: [PATCH 175/216] pkgs/sage-conf_conda/setup.py: Always run configure --- pkgs/sage-conf_conda/setup.py | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/pkgs/sage-conf_conda/setup.py b/pkgs/sage-conf_conda/setup.py index 9e8ac353f4f..bc46900e2d7 100644 --- a/pkgs/sage-conf_conda/setup.py +++ b/pkgs/sage-conf_conda/setup.py @@ -30,22 +30,22 @@ def run(self): if os.path.exists(os.path.join(SAGE_ROOT, 'config.status')): print(f'Reusing configured SAGE_ROOT={SAGE_ROOT}') - else: - cmd = f"cd {SAGE_ROOT} && ./configure --enable-build-as-root --with-system-python3=force --disable-notebook --disable-sagelib --disable-sage_conf --disable-doc" - cmd += ' --with-python=$CONDA_PREFIX/bin/python --prefix="$CONDA_PREFIX"' - cmd += ' $(for pkg in $(PATH="build/bin:$PATH" build/bin/sage-package list :standard: --exclude rpy2 --has-file spkg-configure.m4 --has-file distros/conda.txt); do echo --with-system-$pkg=force; done)' - print(f"Running {cmd}") - sys.stdout.flush() - if os.system(cmd) != 0: - if os.path.exists(os.path.join(SAGE_ROOT, 'config.status')): - print("Warning: A configuration has been written, but the configure script has exited with an error. " - "Carefully check any messages above before continuing.") - else: - print(f"Error: The configure script has failed; this may be caused by missing build prerequisites.") - sys.stdout.flush() - PREREQ_SPKG = "_prereq bzip2 xz libffi" # includes python3 SPKG_DEPCHECK packages - os.system(f'cd {SAGE_ROOT} && export PACKAGES="$(build/bin/sage-get-system-packages conda {PREREQ_SPKG})" && [ -n "$PACKAGES" ] && echo "You can install the required build prerequisites using the following shell command" && echo "" && build/bin/sage-print-system-package-command conda --verbose --sudo install $PACKAGES && echo ""') - raise SetupError("configure failed") + + cmd = f"cd {SAGE_ROOT} && ./configure --enable-build-as-root --with-system-python3=force --disable-notebook --disable-sagelib --disable-sage_conf --disable-doc" + cmd += ' --with-python=$CONDA_PREFIX/bin/python --prefix="$CONDA_PREFIX"' + cmd += ' $(for pkg in $(PATH="build/bin:$PATH" build/bin/sage-package list :standard: --exclude rpy2 --has-file spkg-configure.m4 --has-file distros/conda.txt); do echo --with-system-$pkg=force; done)' + print(f"Running {cmd}") + sys.stdout.flush() + if os.system(cmd) != 0: + if os.path.exists(os.path.join(SAGE_ROOT, 'config.status')): + print("Warning: A configuration has been written, but the configure script has exited with an error. " + "Carefully check any messages above before continuing.") + else: + print(f"Error: The configure script has failed; this may be caused by missing build prerequisites.") + sys.stdout.flush() + PREREQ_SPKG = "_prereq bzip2 xz libffi" # includes python3 SPKG_DEPCHECK packages + os.system(f'cd {SAGE_ROOT} && export PACKAGES="$(build/bin/sage-get-system-packages conda {PREREQ_SPKG})" && [ -n "$PACKAGES" ] && echo "You can install the required build prerequisites using the following shell command" && echo "" && build/bin/sage-print-system-package-command conda --verbose --sudo install $PACKAGES && echo ""') + raise SetupError("configure failed") # In this mode, we never run "make". From d0cae8008f7b56f8fc752a5e297c785f3150e0d3 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 12 Oct 2023 09:10:12 -0700 Subject: [PATCH 176/216] pkgs/sage-conf_conda/setup.py: Remove 'reusing configured SAGE_ROOT' message --- pkgs/sage-conf_conda/setup.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/pkgs/sage-conf_conda/setup.py b/pkgs/sage-conf_conda/setup.py index bc46900e2d7..96f163dfe5a 100644 --- a/pkgs/sage-conf_conda/setup.py +++ b/pkgs/sage-conf_conda/setup.py @@ -28,9 +28,6 @@ def run(self): raise SetupError('No conda environment is active. ' 'See https://doc.sagemath.org/html/en/installation/conda.html on how to get started.') - if os.path.exists(os.path.join(SAGE_ROOT, 'config.status')): - print(f'Reusing configured SAGE_ROOT={SAGE_ROOT}') - cmd = f"cd {SAGE_ROOT} && ./configure --enable-build-as-root --with-system-python3=force --disable-notebook --disable-sagelib --disable-sage_conf --disable-doc" cmd += ' --with-python=$CONDA_PREFIX/bin/python --prefix="$CONDA_PREFIX"' cmd += ' $(for pkg in $(PATH="build/bin:$PATH" build/bin/sage-package list :standard: --exclude rpy2 --has-file spkg-configure.m4 --has-file distros/conda.txt); do echo --with-system-$pkg=force; done)' From 285966f6ad73e4db61b32c41fd952babb23645d1 Mon Sep 17 00:00:00 2001 From: Dave Witte Morris Date: Fri, 13 Oct 2023 11:24:23 -0600 Subject: [PATCH 177/216] #36153 fix legend_color KeyError --- src/sage/combinat/root_system/plot.py | 2 +- src/sage/plot/arrow.py | 9 ++++++++- src/sage/plot/circle.py | 4 ++++ src/sage/plot/disk.py | 6 +++++- src/sage/plot/ellipse.py | 5 +++++ src/sage/plot/point.py | 4 ++++ src/sage/plot/polygon.py | 7 ++++++- 7 files changed, 33 insertions(+), 4 deletions(-) diff --git a/src/sage/combinat/root_system/plot.py b/src/sage/combinat/root_system/plot.py index 34c178cef8f..a1eec40e8df 100644 --- a/src/sage/combinat/root_system/plot.py +++ b/src/sage/combinat/root_system/plot.py @@ -1349,7 +1349,7 @@ def cone(self, rays=[], lines=[], color="black", thickness=1, alpha=1, wireframe - ``alpha`` -- a number in the interval `[0, 1]` (default: `1`) the desired transparency - - ``label`` -- an object to be used as for this cone. + - ``label`` -- an object to be used as the label for this cone. The label itself will be constructed by calling :func:`~sage.misc.latex.latex` or :func:`repr` on the object depending on the graphics backend. diff --git a/src/sage/plot/arrow.py b/src/sage/plot/arrow.py index 179e026d2e4..f5baa03d8d9 100644 --- a/src/sage/plot/arrow.py +++ b/src/sage/plot/arrow.py @@ -489,7 +489,8 @@ def arrow(tailpoint=None, headpoint=None, **kwds): @rename_keyword(color='rgbcolor') -@options(width=2, rgbcolor=(0,0,1), zorder=2, head=1, linestyle='solid', legend_label=None) +@options(width=2, rgbcolor=(0,0,1), zorder=2, head=1, linestyle='solid', + legend_label=None, legend_color=None) def arrow2d(tailpoint=None, headpoint=None, path=None, **options): """ If ``tailpoint`` and ``headpoint`` are provided, returns an arrow from @@ -640,6 +641,12 @@ def arrow2d(tailpoint=None, headpoint=None, path=None, **options): :: sage: arrow2d((-2,2), (7,1)).show(frame=True) + + TESTS: + + Verify that :trac:`36153` is fixed:: + + sage: A = arrow2d((-1,-1), (2,3), legend_label="test") """ from sage.plot.all import Graphics g = Graphics() diff --git a/src/sage/plot/circle.py b/src/sage/plot/circle.py index 41281b66735..1134be434b1 100644 --- a/src/sage/plot/circle.py +++ b/src/sage/plot/circle.py @@ -406,6 +406,10 @@ def circle(center, radius, **options): sage: P = circle((1,1), 1) sage: P.aspect_ratio() 1.0 + + Verify that :trac:`36153` does not arise:: + + sage: C = circle((1,1), 1, legend_label="test") """ from sage.plot.all import Graphics diff --git a/src/sage/plot/disk.py b/src/sage/plot/disk.py index 91891b84550..bbc79394810 100644 --- a/src/sage/plot/disk.py +++ b/src/sage/plot/disk.py @@ -247,7 +247,7 @@ def plot3d(self, z=0, **kwds): @rename_keyword(color='rgbcolor') @options(alpha=1, fill=True, rgbcolor=(0, 0, 1), thickness=0, legend_label=None, - aspect_ratio=1.0) + legend_color=None, aspect_ratio=1.0) def disk(point, radius, angle, **options): r""" A disk (that is, a sector or wedge of a circle) with center @@ -346,6 +346,10 @@ def disk(point, radius, angle, **options): Traceback (most recent call last): ... ValueError: the center point of a plotted disk should have two or three coordinates + + Verify that :trac:`36153` is fixed:: + + sage: D = disk((0, 0), 5, (0, pi/2), legend_label="test") """ from sage.plot.all import Graphics g = Graphics() diff --git a/src/sage/plot/ellipse.py b/src/sage/plot/ellipse.py index 791b719fe68..d483996ae88 100644 --- a/src/sage/plot/ellipse.py +++ b/src/sage/plot/ellipse.py @@ -345,6 +345,11 @@ def ellipse(center, r1, r2, angle=0, **options): E=ellipse((0,0),2,1,legend_label="My ellipse", legend_color='green') sphinx_plot(E) + TESTS: + + Verify that :trac:`36153` does not arise:: + + sage: E = ellipse((0,0), 2, 1, legend_label="test") """ from sage.plot.all import Graphics g = Graphics() diff --git a/src/sage/plot/point.py b/src/sage/plot/point.py index 2bbe8cef07a..a689b152bc8 100644 --- a/src/sage/plot/point.py +++ b/src/sage/plot/point.py @@ -579,6 +579,10 @@ def point2d(points, **options): sage: point2d(iter([])) Graphics object consisting of 0 graphics primitives + + Verify that :trac:`36153` does not arise:: + + sage: P = point((0.5, 0.5), legend_label="test") """ from sage.plot.plot import xydata_from_point_list from sage.plot.all import Graphics diff --git a/src/sage/plot/polygon.py b/src/sage/plot/polygon.py index 6f2c2b3f78b..86d0d6599c6 100644 --- a/src/sage/plot/polygon.py +++ b/src/sage/plot/polygon.py @@ -524,10 +524,15 @@ def polygon2d(points, **options): sage: polygon2d([[1,2], [5,6], [5,0]]).aspect_ratio() 1.0 + TESTS: + + Verify that :trac:`36153` does not arise:: + + sage: P = polygon2d([[1,2], [5,6], [5,0]], legend_label="test") + AUTHORS: - David Joyner (2006-04-14): the long list of examples above. - """ from sage.plot.plot import xydata_from_point_list from sage.plot.all import Graphics From 4c4218bef2f32265e60cde1f4811edbdf3bd5b1a Mon Sep 17 00:00:00 2001 From: Alex J Best Date: Sat, 14 Oct 2023 15:51:51 +0100 Subject: [PATCH 178/216] Update src/sage/rings/polynomial/multi_polynomial_libsingular.pyx --- src/sage/rings/polynomial/multi_polynomial_libsingular.pyx | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx b/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx index 9d3f613a5c7..30d9239c003 100644 --- a/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx +++ b/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx @@ -4490,8 +4490,6 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): Traceback (most recent call last): ... ValueError: polynomial is not in the ideal - sage: f.lift(I) - [1, x2] Check that we can work over the integers:: From 0c50d6ac466d40cadb90eb6df266f6ddb6aa3997 Mon Sep 17 00:00:00 2001 From: Alex J Best Date: Sat, 14 Oct 2023 15:52:03 +0100 Subject: [PATCH 179/216] Update src/sage/rings/polynomial/multi_polynomial_libsingular.pyx --- src/sage/rings/polynomial/multi_polynomial_libsingular.pyx | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx b/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx index 30d9239c003..8b1086714f5 100644 --- a/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx +++ b/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx @@ -4502,8 +4502,6 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): Traceback (most recent call last): ... ValueError: polynomial is not in the ideal - sage: f.lift(I) - [1, x2] sage: A. = PolynomialRing(ZZ,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 From f2dfb7b868352236cca348ad335be1ebe662617f Mon Sep 17 00:00:00 2001 From: Dave Witte Morris Date: Sat, 14 Oct 2023 08:58:12 -0600 Subject: [PATCH 180/216] change :trac: to :issue: --- src/sage/plot/arrow.py | 2 +- src/sage/plot/circle.py | 2 +- src/sage/plot/disk.py | 2 +- src/sage/plot/ellipse.py | 2 +- src/sage/plot/point.py | 2 +- src/sage/plot/polygon.py | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/sage/plot/arrow.py b/src/sage/plot/arrow.py index f5baa03d8d9..26bb131f713 100644 --- a/src/sage/plot/arrow.py +++ b/src/sage/plot/arrow.py @@ -644,7 +644,7 @@ def arrow2d(tailpoint=None, headpoint=None, path=None, **options): TESTS: - Verify that :trac:`36153` is fixed:: + Verify that :issue:`36153` is fixed:: sage: A = arrow2d((-1,-1), (2,3), legend_label="test") """ diff --git a/src/sage/plot/circle.py b/src/sage/plot/circle.py index 1134be434b1..c7fd3d9dfc0 100644 --- a/src/sage/plot/circle.py +++ b/src/sage/plot/circle.py @@ -407,7 +407,7 @@ def circle(center, radius, **options): sage: P.aspect_ratio() 1.0 - Verify that :trac:`36153` does not arise:: + Verify that :issue:`36153` does not arise:: sage: C = circle((1,1), 1, legend_label="test") """ diff --git a/src/sage/plot/disk.py b/src/sage/plot/disk.py index bbc79394810..3b2c72051b9 100644 --- a/src/sage/plot/disk.py +++ b/src/sage/plot/disk.py @@ -347,7 +347,7 @@ def disk(point, radius, angle, **options): ... ValueError: the center point of a plotted disk should have two or three coordinates - Verify that :trac:`36153` is fixed:: + Verify that :issue:`36153` is fixed:: sage: D = disk((0, 0), 5, (0, pi/2), legend_label="test") """ diff --git a/src/sage/plot/ellipse.py b/src/sage/plot/ellipse.py index d483996ae88..821906ecf0a 100644 --- a/src/sage/plot/ellipse.py +++ b/src/sage/plot/ellipse.py @@ -347,7 +347,7 @@ def ellipse(center, r1, r2, angle=0, **options): TESTS: - Verify that :trac:`36153` does not arise:: + Verify that :issue:`36153` does not arise:: sage: E = ellipse((0,0), 2, 1, legend_label="test") """ diff --git a/src/sage/plot/point.py b/src/sage/plot/point.py index a689b152bc8..7e880ca3c1c 100644 --- a/src/sage/plot/point.py +++ b/src/sage/plot/point.py @@ -580,7 +580,7 @@ def point2d(points, **options): sage: point2d(iter([])) Graphics object consisting of 0 graphics primitives - Verify that :trac:`36153` does not arise:: + Verify that :issue:`36153` does not arise:: sage: P = point((0.5, 0.5), legend_label="test") """ diff --git a/src/sage/plot/polygon.py b/src/sage/plot/polygon.py index 86d0d6599c6..a2159fcfb56 100644 --- a/src/sage/plot/polygon.py +++ b/src/sage/plot/polygon.py @@ -526,7 +526,7 @@ def polygon2d(points, **options): TESTS: - Verify that :trac:`36153` does not arise:: + Verify that :issue:`36153` does not arise:: sage: P = polygon2d([[1,2], [5,6], [5,0]], legend_label="test") From b7c1c8fe5cd0235a8c28d41d18a16dcbb9f10391 Mon Sep 17 00:00:00 2001 From: Release Manager Date: Sun, 15 Oct 2023 01:09:15 +0200 Subject: [PATCH 181/216] Updated SageMath version to 10.2.beta7 --- CITATION.cff | 4 ++-- VERSION.txt | 2 +- build/pkgs/configure/checksums.ini | 6 +++--- build/pkgs/configure/package-version.txt | 2 +- build/pkgs/sage_conf/install-requires.txt | 2 +- build/pkgs/sage_docbuild/install-requires.txt | 2 +- build/pkgs/sage_setup/install-requires.txt | 2 +- build/pkgs/sage_sws2rst/install-requires.txt | 2 +- build/pkgs/sagelib/install-requires.txt | 2 +- build/pkgs/sagemath_bliss/install-requires.txt | 2 +- build/pkgs/sagemath_categories/install-requires.txt | 2 +- build/pkgs/sagemath_coxeter3/install-requires.txt | 2 +- build/pkgs/sagemath_environment/install-requires.txt | 2 +- build/pkgs/sagemath_mcqd/install-requires.txt | 2 +- build/pkgs/sagemath_meataxe/install-requires.txt | 2 +- build/pkgs/sagemath_objects/install-requires.txt | 2 +- build/pkgs/sagemath_repl/install-requires.txt | 2 +- build/pkgs/sagemath_sirocco/install-requires.txt | 2 +- build/pkgs/sagemath_tdlib/install-requires.txt | 2 +- pkgs/sage-conf/VERSION.txt | 2 +- pkgs/sage-conf_conda/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-bliss/VERSION.txt | 2 +- pkgs/sagemath-categories/VERSION.txt | 2 +- pkgs/sagemath-coxeter3/VERSION.txt | 2 +- pkgs/sagemath-environment/VERSION.txt | 2 +- pkgs/sagemath-mcqd/VERSION.txt | 2 +- pkgs/sagemath-meataxe/VERSION.txt | 2 +- pkgs/sagemath-objects/VERSION.txt | 2 +- pkgs/sagemath-repl/VERSION.txt | 2 +- pkgs/sagemath-sirocco/VERSION.txt | 2 +- pkgs/sagemath-tdlib/VERSION.txt | 2 +- src/VERSION.txt | 2 +- src/bin/sage-version.sh | 6 +++--- src/sage/version.py | 6 +++--- 38 files changed, 45 insertions(+), 45 deletions(-) diff --git a/CITATION.cff b/CITATION.cff index a4eaeb56424..c77984d3dbb 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -4,8 +4,8 @@ title: SageMath abstract: SageMath is a free open-source mathematics software system. authors: - name: "The SageMath Developers" -version: 10.2.beta6 +version: 10.2.beta7 doi: 10.5281/zenodo.593563 -date-released: 2023-10-08 +date-released: 2023-10-14 repository-code: "https://github.com/sagemath/sage" url: "https://www.sagemath.org/" diff --git a/VERSION.txt b/VERSION.txt index 9d2185159cb..ec49d33b7ae 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -1 +1 @@ -SageMath version 10.2.beta6, Release Date: 2023-10-08 +SageMath version 10.2.beta7, Release Date: 2023-10-14 diff --git a/build/pkgs/configure/checksums.ini b/build/pkgs/configure/checksums.ini index 631c6f86cc4..d703578547b 100644 --- a/build/pkgs/configure/checksums.ini +++ b/build/pkgs/configure/checksums.ini @@ -1,4 +1,4 @@ tarball=configure-VERSION.tar.gz -sha1=f922495a00292e1c2c4ab649282647e8f9086ef5 -md5=b9998145d9a1de9257e0eed38d37d204 -cksum=2613207786 +sha1=d00890d9ecb95b96d06007dd383ce32d7eb2d814 +md5=54f3dfffc2ce304135d3db1c0aad5905 +cksum=649734943 diff --git a/build/pkgs/configure/package-version.txt b/build/pkgs/configure/package-version.txt index 14ec2a1e36b..3ecdf8dba78 100644 --- a/build/pkgs/configure/package-version.txt +++ b/build/pkgs/configure/package-version.txt @@ -1 +1 @@ -c697dde8a5c3fe03af4c711b1b837592c5222b8e +a84c11dd8244bf18bcc4bfe5fe4e6adde20ff9ff diff --git a/build/pkgs/sage_conf/install-requires.txt b/build/pkgs/sage_conf/install-requires.txt index 1a1aeb82ccf..5fd72b717b4 100644 --- a/build/pkgs/sage_conf/install-requires.txt +++ b/build/pkgs/sage_conf/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sage-conf ~= 10.2b6 +sage-conf ~= 10.2b7 diff --git a/build/pkgs/sage_docbuild/install-requires.txt b/build/pkgs/sage_docbuild/install-requires.txt index 835830b3029..4cae2a6bf49 100644 --- a/build/pkgs/sage_docbuild/install-requires.txt +++ b/build/pkgs/sage_docbuild/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sage-docbuild ~= 10.2b6 +sage-docbuild ~= 10.2b7 diff --git a/build/pkgs/sage_setup/install-requires.txt b/build/pkgs/sage_setup/install-requires.txt index b6780898e72..68cdb24f9e3 100644 --- a/build/pkgs/sage_setup/install-requires.txt +++ b/build/pkgs/sage_setup/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sage-setup ~= 10.2b6 +sage-setup ~= 10.2b7 diff --git a/build/pkgs/sage_sws2rst/install-requires.txt b/build/pkgs/sage_sws2rst/install-requires.txt index 8529dd6a649..42e83833944 100644 --- a/build/pkgs/sage_sws2rst/install-requires.txt +++ b/build/pkgs/sage_sws2rst/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sage-sws2rst ~= 10.2b6 +sage-sws2rst ~= 10.2b7 diff --git a/build/pkgs/sagelib/install-requires.txt b/build/pkgs/sagelib/install-requires.txt index fa3739fb0e2..5c15582c630 100644 --- a/build/pkgs/sagelib/install-requires.txt +++ b/build/pkgs/sagelib/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-standard ~= 10.2b6 +sagemath-standard ~= 10.2b7 diff --git a/build/pkgs/sagemath_bliss/install-requires.txt b/build/pkgs/sagemath_bliss/install-requires.txt index a183832680d..a3fac16d0c2 100644 --- a/build/pkgs/sagemath_bliss/install-requires.txt +++ b/build/pkgs/sagemath_bliss/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-bliss ~= 10.2b6 +sagemath-bliss ~= 10.2b7 diff --git a/build/pkgs/sagemath_categories/install-requires.txt b/build/pkgs/sagemath_categories/install-requires.txt index deb3d72aaf6..418ff006558 100644 --- a/build/pkgs/sagemath_categories/install-requires.txt +++ b/build/pkgs/sagemath_categories/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-categories ~= 10.2b6 +sagemath-categories ~= 10.2b7 diff --git a/build/pkgs/sagemath_coxeter3/install-requires.txt b/build/pkgs/sagemath_coxeter3/install-requires.txt index b91e7012431..80175254b35 100644 --- a/build/pkgs/sagemath_coxeter3/install-requires.txt +++ b/build/pkgs/sagemath_coxeter3/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-coxeter3 ~= 10.2b6 +sagemath-coxeter3 ~= 10.2b7 diff --git a/build/pkgs/sagemath_environment/install-requires.txt b/build/pkgs/sagemath_environment/install-requires.txt index f874eb9227e..e5f989444fb 100644 --- a/build/pkgs/sagemath_environment/install-requires.txt +++ b/build/pkgs/sagemath_environment/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-environment ~= 10.2b6 +sagemath-environment ~= 10.2b7 diff --git a/build/pkgs/sagemath_mcqd/install-requires.txt b/build/pkgs/sagemath_mcqd/install-requires.txt index 8de59efbee8..bf72ffd0cd0 100644 --- a/build/pkgs/sagemath_mcqd/install-requires.txt +++ b/build/pkgs/sagemath_mcqd/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-mcqd ~= 10.2b6 +sagemath-mcqd ~= 10.2b7 diff --git a/build/pkgs/sagemath_meataxe/install-requires.txt b/build/pkgs/sagemath_meataxe/install-requires.txt index 0e8a89d1a73..2f0417b00e2 100644 --- a/build/pkgs/sagemath_meataxe/install-requires.txt +++ b/build/pkgs/sagemath_meataxe/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-meataxe ~= 10.2b6 +sagemath-meataxe ~= 10.2b7 diff --git a/build/pkgs/sagemath_objects/install-requires.txt b/build/pkgs/sagemath_objects/install-requires.txt index e35a3687836..c2012d49e4f 100644 --- a/build/pkgs/sagemath_objects/install-requires.txt +++ b/build/pkgs/sagemath_objects/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-objects ~= 10.2b6 +sagemath-objects ~= 10.2b7 diff --git a/build/pkgs/sagemath_repl/install-requires.txt b/build/pkgs/sagemath_repl/install-requires.txt index 1a3de989424..dea07d5aadc 100644 --- a/build/pkgs/sagemath_repl/install-requires.txt +++ b/build/pkgs/sagemath_repl/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-repl ~= 10.2b6 +sagemath-repl ~= 10.2b7 diff --git a/build/pkgs/sagemath_sirocco/install-requires.txt b/build/pkgs/sagemath_sirocco/install-requires.txt index fd64729fbea..28d12c2352d 100644 --- a/build/pkgs/sagemath_sirocco/install-requires.txt +++ b/build/pkgs/sagemath_sirocco/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-sirocco ~= 10.2b6 +sagemath-sirocco ~= 10.2b7 diff --git a/build/pkgs/sagemath_tdlib/install-requires.txt b/build/pkgs/sagemath_tdlib/install-requires.txt index 62ca038c083..a41568f6dfa 100644 --- a/build/pkgs/sagemath_tdlib/install-requires.txt +++ b/build/pkgs/sagemath_tdlib/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-tdlib ~= 10.2b6 +sagemath-tdlib ~= 10.2b7 diff --git a/pkgs/sage-conf/VERSION.txt b/pkgs/sage-conf/VERSION.txt index 71e18f87543..e3fab2e6628 100644 --- a/pkgs/sage-conf/VERSION.txt +++ b/pkgs/sage-conf/VERSION.txt @@ -1 +1 @@ -10.2.beta6 +10.2.beta7 diff --git a/pkgs/sage-conf_conda/VERSION.txt b/pkgs/sage-conf_conda/VERSION.txt index 71e18f87543..e3fab2e6628 100644 --- a/pkgs/sage-conf_conda/VERSION.txt +++ b/pkgs/sage-conf_conda/VERSION.txt @@ -1 +1 @@ -10.2.beta6 +10.2.beta7 diff --git a/pkgs/sage-conf_pypi/VERSION.txt b/pkgs/sage-conf_pypi/VERSION.txt index 71e18f87543..e3fab2e6628 100644 --- a/pkgs/sage-conf_pypi/VERSION.txt +++ b/pkgs/sage-conf_pypi/VERSION.txt @@ -1 +1 @@ -10.2.beta6 +10.2.beta7 diff --git a/pkgs/sage-docbuild/VERSION.txt b/pkgs/sage-docbuild/VERSION.txt index 71e18f87543..e3fab2e6628 100644 --- a/pkgs/sage-docbuild/VERSION.txt +++ b/pkgs/sage-docbuild/VERSION.txt @@ -1 +1 @@ -10.2.beta6 +10.2.beta7 diff --git a/pkgs/sage-setup/VERSION.txt b/pkgs/sage-setup/VERSION.txt index 71e18f87543..e3fab2e6628 100644 --- a/pkgs/sage-setup/VERSION.txt +++ b/pkgs/sage-setup/VERSION.txt @@ -1 +1 @@ -10.2.beta6 +10.2.beta7 diff --git a/pkgs/sage-sws2rst/VERSION.txt b/pkgs/sage-sws2rst/VERSION.txt index 71e18f87543..e3fab2e6628 100644 --- a/pkgs/sage-sws2rst/VERSION.txt +++ b/pkgs/sage-sws2rst/VERSION.txt @@ -1 +1 @@ -10.2.beta6 +10.2.beta7 diff --git a/pkgs/sagemath-bliss/VERSION.txt b/pkgs/sagemath-bliss/VERSION.txt index 71e18f87543..e3fab2e6628 100644 --- a/pkgs/sagemath-bliss/VERSION.txt +++ b/pkgs/sagemath-bliss/VERSION.txt @@ -1 +1 @@ -10.2.beta6 +10.2.beta7 diff --git a/pkgs/sagemath-categories/VERSION.txt b/pkgs/sagemath-categories/VERSION.txt index 71e18f87543..e3fab2e6628 100644 --- a/pkgs/sagemath-categories/VERSION.txt +++ b/pkgs/sagemath-categories/VERSION.txt @@ -1 +1 @@ -10.2.beta6 +10.2.beta7 diff --git a/pkgs/sagemath-coxeter3/VERSION.txt b/pkgs/sagemath-coxeter3/VERSION.txt index 71e18f87543..e3fab2e6628 100644 --- a/pkgs/sagemath-coxeter3/VERSION.txt +++ b/pkgs/sagemath-coxeter3/VERSION.txt @@ -1 +1 @@ -10.2.beta6 +10.2.beta7 diff --git a/pkgs/sagemath-environment/VERSION.txt b/pkgs/sagemath-environment/VERSION.txt index 71e18f87543..e3fab2e6628 100644 --- a/pkgs/sagemath-environment/VERSION.txt +++ b/pkgs/sagemath-environment/VERSION.txt @@ -1 +1 @@ -10.2.beta6 +10.2.beta7 diff --git a/pkgs/sagemath-mcqd/VERSION.txt b/pkgs/sagemath-mcqd/VERSION.txt index 71e18f87543..e3fab2e6628 100644 --- a/pkgs/sagemath-mcqd/VERSION.txt +++ b/pkgs/sagemath-mcqd/VERSION.txt @@ -1 +1 @@ -10.2.beta6 +10.2.beta7 diff --git a/pkgs/sagemath-meataxe/VERSION.txt b/pkgs/sagemath-meataxe/VERSION.txt index 71e18f87543..e3fab2e6628 100644 --- a/pkgs/sagemath-meataxe/VERSION.txt +++ b/pkgs/sagemath-meataxe/VERSION.txt @@ -1 +1 @@ -10.2.beta6 +10.2.beta7 diff --git a/pkgs/sagemath-objects/VERSION.txt b/pkgs/sagemath-objects/VERSION.txt index 71e18f87543..e3fab2e6628 100644 --- a/pkgs/sagemath-objects/VERSION.txt +++ b/pkgs/sagemath-objects/VERSION.txt @@ -1 +1 @@ -10.2.beta6 +10.2.beta7 diff --git a/pkgs/sagemath-repl/VERSION.txt b/pkgs/sagemath-repl/VERSION.txt index 71e18f87543..e3fab2e6628 100644 --- a/pkgs/sagemath-repl/VERSION.txt +++ b/pkgs/sagemath-repl/VERSION.txt @@ -1 +1 @@ -10.2.beta6 +10.2.beta7 diff --git a/pkgs/sagemath-sirocco/VERSION.txt b/pkgs/sagemath-sirocco/VERSION.txt index 71e18f87543..e3fab2e6628 100644 --- a/pkgs/sagemath-sirocco/VERSION.txt +++ b/pkgs/sagemath-sirocco/VERSION.txt @@ -1 +1 @@ -10.2.beta6 +10.2.beta7 diff --git a/pkgs/sagemath-tdlib/VERSION.txt b/pkgs/sagemath-tdlib/VERSION.txt index 71e18f87543..e3fab2e6628 100644 --- a/pkgs/sagemath-tdlib/VERSION.txt +++ b/pkgs/sagemath-tdlib/VERSION.txt @@ -1 +1 @@ -10.2.beta6 +10.2.beta7 diff --git a/src/VERSION.txt b/src/VERSION.txt index 71e18f87543..e3fab2e6628 100644 --- a/src/VERSION.txt +++ b/src/VERSION.txt @@ -1 +1 @@ -10.2.beta6 +10.2.beta7 diff --git a/src/bin/sage-version.sh b/src/bin/sage-version.sh index cb6b55a9f90..d4d11cb418d 100644 --- a/src/bin/sage-version.sh +++ b/src/bin/sage-version.sh @@ -4,6 +4,6 @@ # which stops "setup.py develop" from rewriting it as a Python file. : # This file is auto-generated by the sage-update-version script, do not edit! -SAGE_VERSION='10.2.beta6' -SAGE_RELEASE_DATE='2023-10-08' -SAGE_VERSION_BANNER='SageMath version 10.2.beta6, Release Date: 2023-10-08' +SAGE_VERSION='10.2.beta7' +SAGE_RELEASE_DATE='2023-10-14' +SAGE_VERSION_BANNER='SageMath version 10.2.beta7, Release Date: 2023-10-14' diff --git a/src/sage/version.py b/src/sage/version.py index 338430c34c8..fac8596b5fa 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 = '10.2.beta6' -date = '2023-10-08' -banner = 'SageMath version 10.2.beta6, Release Date: 2023-10-08' +version = '10.2.beta7' +date = '2023-10-14' +banner = 'SageMath version 10.2.beta7, Release Date: 2023-10-14' From a70ef8ba92de66802fe306ae82b84572eab3b1fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Sun, 15 Oct 2023 09:05:44 +0200 Subject: [PATCH 182/216] fix the linters again --- src/sage/graphs/graph.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/sage/graphs/graph.py b/src/sage/graphs/graph.py index 718dbdad745..4c41ed7d0a8 100644 --- a/src/sage/graphs/graph.py +++ b/src/sage/graphs/graph.py @@ -5005,8 +5005,8 @@ def minor(self, H, solver=None, verbose=0, induced=False, *, integrality_toleran sage: gg.is_isomorphic(h) True - TESTS:: - + TESTS: + A graph `g` may have a minor isomorphic to a given graph `h` but no induced minor isomorphic to `h`:: @@ -5095,7 +5095,7 @@ def minor(self, H, solver=None, verbose=0, induced=False, *, integrality_toleran # if induced is True # condition for induced subgraph ensures that if there - # doesnt exist an edge(h1, h2) in H then there should + # doesnt exist an edge(h1, h2) in H then there should # not be an edge between representative sets of h1 and h2 in G if induced: for h1, h2 in H.complement().edge_iterator(labels=False): @@ -5108,7 +5108,7 @@ def minor(self, H, solver=None, verbose=0, induced=False, *, integrality_toleran try: p.solve(log=verbose) except MIPSolverException: - if induced: + if induced: raise ValueError("This graph has no induced minor isomorphic to H !") else: raise ValueError("This graph has no minor isomorphic to H !") @@ -6657,7 +6657,7 @@ def cliques_maximal(self, algorithm="native"): raise ValueError("Algorithm must be equal to 'native' or to 'NetworkX'.") @doc_index("Clique-related methods") - def clique_maximum(self, algorithm="Cliquer", solver=None, verbose=0, + def clique_maximum(self, algorithm="Cliquer", solver=None, verbose=0, *, integrality_tolerance=1e-3): """ Return the vertex set of a maximal order complete subgraph. @@ -6901,7 +6901,7 @@ def cliques_number_of(self, vertices=None, cliques=None): for c in cliques: count.update(c) - return {v : count[v] for v in vertices or self} + return {v: count[v] for v in vertices or self} @doc_index("Clique-related methods") def cliques_get_max_clique_graph(self): @@ -7653,7 +7653,7 @@ def cliques_containing_vertex(self, vertices=None, cliques=None): for v in c: d[v].append(c) - return {v : d[v] for v in vertices or self} + return {v: d[v] for v in vertices or self} @doc_index("Clique-related methods") def clique_complex(self): From 1ae2c55615ab56a81b8b24638fdee0f13b07d670 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Sun, 15 Oct 2023 12:30:12 +0200 Subject: [PATCH 183/216] remove unused variables in pyx files in groups/ --- .../partn_ref/canonical_augmentation.pyx | 9 ++------ .../perm_gps/partn_ref/data_structures.pyx | 22 +++++-------------- .../perm_gps/partn_ref/refinement_binary.pyx | 20 ++++++++--------- .../perm_gps/partn_ref/refinement_graphs.pyx | 11 +++------- 4 files changed, 19 insertions(+), 43 deletions(-) diff --git a/src/sage/groups/perm_gps/partn_ref/canonical_augmentation.pyx b/src/sage/groups/perm_gps/partn_ref/canonical_augmentation.pyx index d6cc56d585a..680dbf5675d 100644 --- a/src/sage/groups/perm_gps/partn_ref/canonical_augmentation.pyx +++ b/src/sage/groups/perm_gps/partn_ref/canonical_augmentation.pyx @@ -183,13 +183,9 @@ cdef void *canonical_generator_next(void *can_gen_data, int *degree, bint *mem_e cdef void *next_candidate cdef void *parent_cand cdef void *aug - cdef int i, next_cand_deg, parent_cand_deg - cdef int *isom + cdef int next_cand_deg, parent_cand_deg cdef PartitionStack *part cdef bint augmentation_is_canonical - cdef aut_gp_and_can_lab *output - cdef agcl_work_space *agcl_ws - cdef dc_work_space *dc_ws if cgd.level == 0: if cgd.mem_err: @@ -344,6 +340,7 @@ cdef canonical_generator_data *allocate_cgd(int max_depth, int degree): cgd.degree_stack[0] = degree return cgd + cdef void deallocate_cgd(canonical_generator_data *cgd): r""" Deallocate the data part of the canonical generation iterator struct. @@ -351,8 +348,6 @@ cdef void deallocate_cgd(canonical_generator_data *cgd): if cgd is NULL: return cdef int i - cdef void *thingy - cdef void (*clearer)(void*) for i from 0 <= i < cgd.allocd_levels: if cgd.agcl_work_spaces[i] is not NULL: deallocate_agcl_work_space(cgd.agcl_work_spaces[i]) diff --git a/src/sage/groups/perm_gps/partn_ref/data_structures.pyx b/src/sage/groups/perm_gps/partn_ref/data_structures.pyx index c3b87a3bc1f..285c1afd1eb 100644 --- a/src/sage/groups/perm_gps/partn_ref/data_structures.pyx +++ b/src/sage/groups/perm_gps/partn_ref/data_structures.pyx @@ -45,7 +45,6 @@ cdef inline OrbitPartition *OP_new(int n): Allocate and return a pointer to a new OrbitPartition of degree n. Returns a null pointer in the case of an allocation failure. """ - cdef int i cdef OrbitPartition *OP = \ sig_malloc(sizeof(OrbitPartition)) cdef int *int_array = sig_malloc( 4*n * sizeof(int) ) @@ -185,7 +184,6 @@ cdef inline PartitionStack *PS_new(int n, bint unit_partition): Allocate and return a pointer to a new PartitionStack of degree n. Returns a null pointer in the case of an allocation failure. """ - cdef int i cdef PartitionStack *PS = \ sig_malloc(sizeof(PartitionStack)) cdef int *int_array = sig_malloc( 2*n * sizeof(int) ) @@ -210,7 +208,7 @@ cdef void PS_unit_partition(PartitionStack *PS): for i in range(n - 1): PS.entries[i] = i PS.levels[i] = n - PS.entries[n-1] = n-1 + PS.entries[n-1] = n - 1 PS.levels[n-1] = -1 cdef inline PartitionStack *PS_copy(PartitionStack *PS): @@ -218,7 +216,7 @@ cdef inline PartitionStack *PS_copy(PartitionStack *PS): Allocate and return a pointer to a copy of PartitionStack PS. Returns a null pointer in the case of an allocation failure. """ - cdef int i, n = PS.degree + cdef int n = PS.degree cdef PartitionStack *PS2 = \ sig_malloc(sizeof(PartitionStack)) @@ -327,7 +325,6 @@ cdef int PS_all_new_cells(PartitionStack *PS, bitset_t** nonsingletons_ptr): Return the number of rows of ``nonsingletons_ptr``. """ cdef int beg=0, end, n = PS.degree, count=0, i, n_1 = n-1 - cdef bint non_unit_partition = False cdef bitset_t scratch bitset_init(scratch, n) cdef bitset_t* nonsingletons = nonsingletons_ptr[0] @@ -561,10 +558,6 @@ cdef StabilizerChain *SC_new(int n, bint init_gens=True): cdef int i cdef StabilizerChain *SC = \ sig_calloc(1, sizeof(StabilizerChain)) - cdef int *array1 - cdef int *array2 - cdef int *array3 - cdef bint mem_err = 0 if SC is NULL: return NULL SC.degree = n @@ -762,7 +755,6 @@ cdef int SC_realloc_bitsets(StabilizerChain *SC, unsigned long size): cdef unsigned long new_size = size_old while new_size < size: new_size *= 2 - cdef unsigned long limbs_old = SC.gen_used.limbs cdef long limbs = (new_size - 1)/(8*sizeof(unsigned long)) + 1 cdef mp_limb_t *tmp = sig_realloc(SC.gen_used.bits, limbs * sizeof(mp_limb_t)) if tmp is not NULL: @@ -866,7 +858,7 @@ cdef StabilizerChain *SC_new_base(StabilizerChain *SC, int *base, int base_len): return NEW cdef int SC_new_base_nomalloc(StabilizerChain *SC_dest, StabilizerChain *SC, int *base, int base_len): - cdef int i, n = SC.degree + cdef int i SC_dest.base_size = 0 for i in range(base_len): SC_add_base_point(SC_dest, base[i]) @@ -937,7 +929,7 @@ cdef StabilizerChain *SC_insert_base_point(StabilizerChain *SC, int level, int p return NEW cdef int SC_insert_base_point_nomalloc(StabilizerChain *SC_dest, StabilizerChain *SC, int level, int p): - cdef int i, b, n = SC.degree + cdef int i, b SC_copy_nomalloc(SC_dest, SC, level) SC_add_base_point(SC_dest, p) for i in range(level, SC.base_size): @@ -956,7 +948,7 @@ cdef int SC_re_tree(StabilizerChain *SC, int level, int *perm, int x): """ cdef int *gen cdef int *gen_inv - cdef int i, b, gen_index, error, n = SC.degree + cdef int i, b, gen_index, n = SC.degree # make sure we have room for the new generator: if SC.array_size[level] == SC.num_gens[level]: @@ -1027,7 +1019,6 @@ cdef int SC_sift(StabilizerChain *SC, int level, int x, int *gens, int num_gens, cdef int y, b = SC.base_orbits[level][0] cdef int *perm cdef int *perm_rep_inv = temp - cdef int j for i from 0 <= i < num_gens: perm = new_gens + n*i # this is now rs y = perm[b] @@ -1039,7 +1030,6 @@ cdef int SC_sift(StabilizerChain *SC, int level, int x, int *gens, int num_gens, cdef int SC_insert_and_sift(StabilizerChain *SC, int level, int *pi, int num_perms, bint sift): cdef int i, j, b, n = SC.degree cdef int perm_gen_index - cdef int max_orbit_size, max_orbit_place if sift: if SC_realloc_bitsets(SC, num_perms): return 1 @@ -1065,13 +1055,11 @@ cdef int SC_insert_and_sift(StabilizerChain *SC, int level, int *pi, int num_per # Record the old orbit elements and the old generators (see sifting phase) cdef int old_num_gens = SC.num_gens[level] - cdef int old_num_points = SC.orbit_sizes[level] # Add new points to the tree: cdef int x cdef int *perm cdef int start_over = 1 - cdef int error cdef int re_treed = 0 while start_over: start_over = 0 diff --git a/src/sage/groups/perm_gps/partn_ref/refinement_binary.pyx b/src/sage/groups/perm_gps/partn_ref/refinement_binary.pyx index f81ce62060f..06f548f4b7c 100644 --- a/src/sage/groups/perm_gps/partn_ref/refinement_binary.pyx +++ b/src/sage/groups/perm_gps/partn_ref/refinement_binary.pyx @@ -235,9 +235,8 @@ cdef class LinearBinaryCodeStruct(BinaryCodeStruct): sage: B = LinearBinaryCodeStruct(M) sage: B.automorphism_group()[1] 17868913969917295853568000000 - """ - cdef int i, n = self.degree + cdef int n = self.degree cdef PartitionStack *part if partition is None: part = PS_new(n, 1) @@ -650,7 +649,7 @@ cdef int refine_by_bip_degree(PartitionStack *col_ps, void *S, int *cells_to_ref """ cdef BinaryCodeStruct BCS = S cdef int current_cell_against = 0 - cdef int current_cell, i, r, j + cdef int current_cell, i, r cdef int first_largest_subcell cdef int invariant = 0 cdef PartitionStack *word_ps = BCS.word_ps @@ -970,7 +969,7 @@ cdef inline int word_degree(PartitionStack *word_ps, BinaryCodeStruct BCS, int e of PS """ cdef bitset_t cell, word - cdef int i, h + cdef int h bitset_init(cell, BCS.degree) bitset_zero(cell) bitset_init(word, BCS.degree) @@ -1001,7 +1000,7 @@ cdef inline int col_degree(PartitionStack *col_ps, BinaryCodeStruct BCS, int ent """ cdef bitset_t word bitset_init(word, BCS.degree) - cdef int degree = 0, word_basis, i, b + cdef int degree = 0 entry = col_ps.entries[entry] while True: BCS.ith_word(BCS, word_ps.entries[cell_index], word) @@ -1017,15 +1016,14 @@ cdef inline int sort_by_function_codes(PartitionStack *PS, int start, int *degre A simple counting sort, given the degrees of vertices to a certain cell. INPUT: - PS -- the partition stack to be checked - start -- beginning index of the cell to be sorted - degrees -- the values to be sorted by - count, count_max, output -- scratch space + - PS -- the partition stack to be checked + - start -- beginning index of the cell to be sorted + - degrees -- the values to be sorted by + - count, count_max, output -- scratch space """ - cdef int n = PS.degree cdef int i, j, max, max_location - for j from 0 <= j < count_max: + for j in range(count_max): counts[j] = 0 i = 0 while PS.levels[i+start] > PS.depth: diff --git a/src/sage/groups/perm_gps/partn_ref/refinement_graphs.pyx b/src/sage/groups/perm_gps/partn_ref/refinement_graphs.pyx index 5046a718853..cafe8a26c75 100644 --- a/src/sage/groups/perm_gps/partn_ref/refinement_graphs.pyx +++ b/src/sage/groups/perm_gps/partn_ref/refinement_graphs.pyx @@ -65,7 +65,7 @@ def isomorphic(G1, G2, partn, ordering2, dig, use_indicator_function, sparse=Fal cdef GraphStruct GS1 = GraphStruct() cdef GraphStruct GS2 = GraphStruct() cdef GraphStruct GS - cdef int i, j, k, n = -1, cell_len + cdef int i, j, n = -1 cdef list partition, cell cdef bint loops = 0 @@ -131,7 +131,6 @@ def isomorphic(G1, G2, partn, ordering2, dig, use_indicator_function, sparse=Fal raise TypeError("G must be a Sage graph") if first: frm1 = frm - to1 = to else: frm2 = frm to2 = to @@ -464,7 +463,6 @@ def search_tree(G_in, partition, lab=True, dig=False, dict_rep=False, certificat sig_free(GS.scratch) raise MemoryError - lab_new = lab or certificate output = get_aut_gp_and_can_lab(GS, part, G.num_verts, &all_children_are_equivalent, &refine_by_degree, &compare_graphs, lab, NULL, NULL, NULL) sig_free( GS.scratch ) # prepare output @@ -693,7 +691,6 @@ cdef bint all_children_are_equivalent(PartitionStack *PS, void *S): cdef GraphStruct GS = S if GS.directed or GS.loops: return 0 - cdef CGraph G = GS.G cdef int i, n = PS.degree cdef bint in_cell = 0 cdef int nontrivial_cells = 0 @@ -1147,7 +1144,7 @@ cdef void *apply_dg_edge_aug(void *parent, void *aug, void *child, int *degree, cdef GraphStruct GS_child = child, GS_par = parent cdef DenseGraph DG = GS_child.G, DG_par = GS_par.G cdef subset *edge = aug - cdef int u, v, n = DG_par.num_verts + cdef int u, v # copy DG_par edges to DG copy_dense_graph(DG, DG_par) @@ -1353,7 +1350,6 @@ def generate_dense_graphs_edge_addition(int n, bint loops, G=None, depth=None, cdef list out_list cdef void *thing - cdef GraphStruct thing_gs cdef Integer number cdef bint mem_err = 0 if construct: @@ -1476,7 +1472,7 @@ cdef void *canonical_dg_vert_parent(void *child, void *parent, int *permutation, """ cdef GraphStruct GS_par = parent, GS = child cdef DenseGraph DG_par = GS_par.G, DG = GS.G - cdef int u, v, n = DG_par.num_verts + cdef int u, n = DG_par.num_verts cdef int *scratch = GS.scratch # copy DG edges to DG_par @@ -1630,7 +1626,6 @@ def generate_dense_graphs_vert_addition(int n, base_G=None, cdef list out_list cdef void *thing - cdef GraphStruct thing_gs cdef Integer number cdef bint mem_err = 0 if construct: From 12fe59f09025a3fe9eca358427eda531c637fbc9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Sun, 15 Oct 2023 12:33:02 +0200 Subject: [PATCH 184/216] detail fixed --- 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 4c41ed7d0a8..2435bd815b7 100644 --- a/src/sage/graphs/graph.py +++ b/src/sage/graphs/graph.py @@ -5095,7 +5095,7 @@ def minor(self, H, solver=None, verbose=0, induced=False, *, integrality_toleran # if induced is True # condition for induced subgraph ensures that if there - # doesnt exist an edge(h1, h2) in H then there should + # does not exist an edge(h1, h2) in H then there should # not be an edge between representative sets of h1 and h2 in G if induced: for h1, h2 in H.complement().edge_iterator(labels=False): From 72a6ed5dddb14231b7e59da8e9acf2d9d9e77676 Mon Sep 17 00:00:00 2001 From: Michael Orlitzky Date: Sun, 10 Sep 2023 19:27:15 -0400 Subject: [PATCH 185/216] build/pkgs/poetry_core: add Gentoo package information --- build/pkgs/poetry_core/distros/gentoo.txt | 1 + 1 file changed, 1 insertion(+) create mode 100644 build/pkgs/poetry_core/distros/gentoo.txt diff --git a/build/pkgs/poetry_core/distros/gentoo.txt b/build/pkgs/poetry_core/distros/gentoo.txt new file mode 100644 index 00000000000..758fd6e9e01 --- /dev/null +++ b/build/pkgs/poetry_core/distros/gentoo.txt @@ -0,0 +1 @@ +dev-python/poetry-core From c9e20678e8f9e213270ab74a56a4e3f94ba017e3 Mon Sep 17 00:00:00 2001 From: Michael Orlitzky Date: Sun, 10 Sep 2023 19:28:33 -0400 Subject: [PATCH 186/216] build/pkgs/poetry_core: add standard python spkg-configure.m4 --- build/pkgs/poetry_core/spkg-configure.m4 | 1 + 1 file changed, 1 insertion(+) create mode 100644 build/pkgs/poetry_core/spkg-configure.m4 diff --git a/build/pkgs/poetry_core/spkg-configure.m4 b/build/pkgs/poetry_core/spkg-configure.m4 new file mode 100644 index 00000000000..ae5337520e7 --- /dev/null +++ b/build/pkgs/poetry_core/spkg-configure.m4 @@ -0,0 +1 @@ +SAGE_SPKG_CONFIGURE([poetry_core], [SAGE_PYTHON_PACKAGE_CHECK([poetry-core])]) From 8f8394ceb3d1e4434276e20326587ce6e7f72425 Mon Sep 17 00:00:00 2001 From: Dima Pasechnik Date: Fri, 15 Sep 2023 22:03:15 +0100 Subject: [PATCH 187/216] more spkg-configure.m4 for python packages --- build/pkgs/jupyter_packaging/spkg-configure.m4 | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 build/pkgs/jupyter_packaging/spkg-configure.m4 diff --git a/build/pkgs/jupyter_packaging/spkg-configure.m4 b/build/pkgs/jupyter_packaging/spkg-configure.m4 new file mode 100644 index 00000000000..2d3ee6280dd --- /dev/null +++ b/build/pkgs/jupyter_packaging/spkg-configure.m4 @@ -0,0 +1,3 @@ +SAGE_SPKG_CONFIGURE([jupyter_packaging], [ + SAGE_PYTHON_PACKAGE_CHECK([jupyter_packaging]) +]) From 41ed5b3028cbc195a866dcc45d39e19fccce58e5 Mon Sep 17 00:00:00 2001 From: Dima Pasechnik Date: Sat, 16 Sep 2023 12:48:57 +0100 Subject: [PATCH 188/216] 7.1+ does not work with Sage, cf sagemath/sage/pull/35658 see https://github.com/sagemath/sage/pull/35658, in particular https://github.com/sagemath/sage/pull/35658#issuecomment-1722179207 and later --- build/pkgs/sphinx/install-requires.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/pkgs/sphinx/install-requires.txt b/build/pkgs/sphinx/install-requires.txt index 9003fdec2f8..1ad0ea81a41 100644 --- a/build/pkgs/sphinx/install-requires.txt +++ b/build/pkgs/sphinx/install-requires.txt @@ -1 +1 @@ -sphinx >=5.2, <8 +sphinx >=5.2, <7.1 From 76141a62076c7fee35657e8037675828ae34ab66 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 2 Sep 2023 18:36:50 -0700 Subject: [PATCH 189/216] build/pkgs/pkgconfig: Update to 1.5.5, change to wheel package --- build/pkgs/pkgconfig/SPKG.rst | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/build/pkgs/pkgconfig/SPKG.rst b/build/pkgs/pkgconfig/SPKG.rst index 3c5d61a167a..9566fb4e409 100644 --- a/build/pkgs/pkgconfig/SPKG.rst +++ b/build/pkgs/pkgconfig/SPKG.rst @@ -1,19 +1,18 @@ -pkgconfig: Python interface to pkg-config -========================================= +pkgconfig: Interface Python with pkg-config +=========================================== Description ----------- -Pkgconfig is a Python module to interface with the pkg-config command -line tool. +Interface Python with pkg-config License ------- -MIT License - +MIT Upstream Contact ---------------- -https://github.com/matze/pkgconfig +https://pypi.org/project/pkgconfig/ + From 6107a04a7d1501347c6dcc9ffb12689c4c02f140 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 14 Sep 2023 11:39:03 -0700 Subject: [PATCH 190/216] build/pkgs/pkgconfig/SPKG.rst: Restore hand-edited version --- build/pkgs/pkgconfig/SPKG.rst | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/build/pkgs/pkgconfig/SPKG.rst b/build/pkgs/pkgconfig/SPKG.rst index 9566fb4e409..3c5d61a167a 100644 --- a/build/pkgs/pkgconfig/SPKG.rst +++ b/build/pkgs/pkgconfig/SPKG.rst @@ -1,18 +1,19 @@ -pkgconfig: Interface Python with pkg-config -=========================================== +pkgconfig: Python interface to pkg-config +========================================= Description ----------- -Interface Python with pkg-config +Pkgconfig is a Python module to interface with the pkg-config command +line tool. License ------- -MIT +MIT License + Upstream Contact ---------------- -https://pypi.org/project/pkgconfig/ - +https://github.com/matze/pkgconfig From 7d79db5b9e39977774899b325c202ee9c35dc554 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 19 Sep 2023 10:17:53 -0700 Subject: [PATCH 191/216] build/pkgs/poetry_core: Remove (again) --- build/pkgs/poetry_core/distros/gentoo.txt | 1 - build/pkgs/poetry_core/spkg-configure.m4 | 1 - 2 files changed, 2 deletions(-) delete mode 100644 build/pkgs/poetry_core/distros/gentoo.txt delete mode 100644 build/pkgs/poetry_core/spkg-configure.m4 diff --git a/build/pkgs/poetry_core/distros/gentoo.txt b/build/pkgs/poetry_core/distros/gentoo.txt deleted file mode 100644 index 758fd6e9e01..00000000000 --- a/build/pkgs/poetry_core/distros/gentoo.txt +++ /dev/null @@ -1 +0,0 @@ -dev-python/poetry-core diff --git a/build/pkgs/poetry_core/spkg-configure.m4 b/build/pkgs/poetry_core/spkg-configure.m4 deleted file mode 100644 index ae5337520e7..00000000000 --- a/build/pkgs/poetry_core/spkg-configure.m4 +++ /dev/null @@ -1 +0,0 @@ -SAGE_SPKG_CONFIGURE([poetry_core], [SAGE_PYTHON_PACKAGE_CHECK([poetry-core])]) From f073ed1df7fa66c4c5653fa463debff79a41c793 Mon Sep 17 00:00:00 2001 From: Dima Pasechnik Date: Thu, 21 Sep 2023 18:06:30 +0100 Subject: [PATCH 192/216] sphinx 7.x is OK --- build/pkgs/sphinx/install-requires.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/pkgs/sphinx/install-requires.txt b/build/pkgs/sphinx/install-requires.txt index 1ad0ea81a41..9003fdec2f8 100644 --- a/build/pkgs/sphinx/install-requires.txt +++ b/build/pkgs/sphinx/install-requires.txt @@ -1 +1 @@ -sphinx >=5.2, <7.1 +sphinx >=5.2, <8 From bbd75f89b510c7ff272f86a0f5241f7324a92abb Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 21 Sep 2023 12:31:34 -0700 Subject: [PATCH 193/216] build/pkgs/jupyter_packaging: Remove (again) --- build/pkgs/jupyter_packaging/spkg-configure.m4 | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 build/pkgs/jupyter_packaging/spkg-configure.m4 diff --git a/build/pkgs/jupyter_packaging/spkg-configure.m4 b/build/pkgs/jupyter_packaging/spkg-configure.m4 deleted file mode 100644 index 2d3ee6280dd..00000000000 --- a/build/pkgs/jupyter_packaging/spkg-configure.m4 +++ /dev/null @@ -1,3 +0,0 @@ -SAGE_SPKG_CONFIGURE([jupyter_packaging], [ - SAGE_PYTHON_PACKAGE_CHECK([jupyter_packaging]) -]) From 43ac4adc719416855b445a76c647aecf6c75b846 Mon Sep 17 00:00:00 2001 From: Dima Pasechnik Date: Mon, 25 Sep 2023 15:48:38 +0100 Subject: [PATCH 194/216] leftover standard packages without spkg-configures --- build/pkgs/calver/distros/alpine.txt | 1 + build/pkgs/calver/distros/arch.txt | 1 + build/pkgs/calver/distros/freebsd.txt | 1 + build/pkgs/calver/distros/gentoo.txt | 1 + build/pkgs/calver/distros/install-requires.txt | 1 + build/pkgs/calver/distros/macports.txt | 1 + build/pkgs/calver/distros/opensuse.txt | 1 + build/pkgs/calver/distros/package-version.txt | 1 + build/pkgs/calver/distros/void.txt | 1 + build/pkgs/calver/spkg-configure.m4 | 3 +++ build/pkgs/fastjsonschema/distros/alpine.txt | 1 + build/pkgs/fastjsonschema/distros/arch.txt | 1 + build/pkgs/fastjsonschema/distros/debian.txt | 1 + build/pkgs/fastjsonschema/distros/fedora.txt | 1 + build/pkgs/fastjsonschema/distros/freebsd.txt | 1 + build/pkgs/fastjsonschema/distros/gentoo.txt | 1 + build/pkgs/fastjsonschema/distros/macports.txt | 1 + build/pkgs/fastjsonschema/distros/opensuse.txt | 1 + build/pkgs/fastjsonschema/distros/void.txt | 1 + build/pkgs/fastjsonschema/spkg-configure.m4 | 3 +++ build/pkgs/hatch_fancy_pypi_readme/distros/alpine.txt | 1 + build/pkgs/hatch_fancy_pypi_readme/distros/arch.txt | 1 + build/pkgs/hatch_fancy_pypi_readme/distros/debian.txt | 1 + build/pkgs/hatch_fancy_pypi_readme/distros/fedora.txt | 1 + build/pkgs/hatch_fancy_pypi_readme/distros/freebsd.txt | 1 + build/pkgs/hatch_fancy_pypi_readme/distros/gentoo.txt | 1 + build/pkgs/hatch_fancy_pypi_readme/distros/macports.txt | 1 + build/pkgs/hatch_fancy_pypi_readme/distros/opensuse.txt | 1 + build/pkgs/hatch_fancy_pypi_readme/spkg-configure.m4 | 3 +++ build/pkgs/hatch_vcs/distros/alpine.txt | 1 + build/pkgs/hatch_vcs/distros/arch.txt | 1 + build/pkgs/hatch_vcs/distros/debian.txt | 1 + build/pkgs/hatch_vcs/distros/fedora.txt | 1 + build/pkgs/hatch_vcs/distros/freebsd.txt | 1 + build/pkgs/hatch_vcs/distros/gentoo.txt | 1 + build/pkgs/hatch_vcs/distros/macports.txt | 1 + build/pkgs/hatch_vcs/distros/opensuse.txt | 1 + build/pkgs/hatch_vcs/distros/void.txt | 1 + build/pkgs/hatch_vcs/spkg-configure.m4 | 3 +++ build/pkgs/trove_classifiers/distros/alpine.txt | 1 + build/pkgs/trove_classifiers/distros/arch.txt | 1 + build/pkgs/trove_classifiers/distros/fedora.txt | 1 + build/pkgs/trove_classifiers/distros/freebsd.txt | 1 + build/pkgs/trove_classifiers/distros/gentoo.txt | 1 + build/pkgs/trove_classifiers/distros/macports.txt | 1 + build/pkgs/trove_classifiers/spkg-configure.m4 | 3 +++ 46 files changed, 56 insertions(+) create mode 100644 build/pkgs/calver/distros/alpine.txt create mode 100644 build/pkgs/calver/distros/arch.txt create mode 100644 build/pkgs/calver/distros/freebsd.txt create mode 100644 build/pkgs/calver/distros/gentoo.txt create mode 100644 build/pkgs/calver/distros/install-requires.txt create mode 100644 build/pkgs/calver/distros/macports.txt create mode 100644 build/pkgs/calver/distros/opensuse.txt create mode 100644 build/pkgs/calver/distros/package-version.txt create mode 100644 build/pkgs/calver/distros/void.txt create mode 100644 build/pkgs/calver/spkg-configure.m4 create mode 100644 build/pkgs/fastjsonschema/distros/alpine.txt create mode 100644 build/pkgs/fastjsonschema/distros/arch.txt create mode 100644 build/pkgs/fastjsonschema/distros/debian.txt create mode 100644 build/pkgs/fastjsonschema/distros/fedora.txt create mode 100644 build/pkgs/fastjsonschema/distros/freebsd.txt create mode 100644 build/pkgs/fastjsonschema/distros/gentoo.txt create mode 100644 build/pkgs/fastjsonschema/distros/macports.txt create mode 100644 build/pkgs/fastjsonschema/distros/opensuse.txt create mode 100644 build/pkgs/fastjsonschema/distros/void.txt create mode 100644 build/pkgs/fastjsonschema/spkg-configure.m4 create mode 100644 build/pkgs/hatch_fancy_pypi_readme/distros/alpine.txt create mode 100644 build/pkgs/hatch_fancy_pypi_readme/distros/arch.txt create mode 100644 build/pkgs/hatch_fancy_pypi_readme/distros/debian.txt create mode 100644 build/pkgs/hatch_fancy_pypi_readme/distros/fedora.txt create mode 100644 build/pkgs/hatch_fancy_pypi_readme/distros/freebsd.txt create mode 100644 build/pkgs/hatch_fancy_pypi_readme/distros/gentoo.txt create mode 100644 build/pkgs/hatch_fancy_pypi_readme/distros/macports.txt create mode 100644 build/pkgs/hatch_fancy_pypi_readme/distros/opensuse.txt create mode 100644 build/pkgs/hatch_fancy_pypi_readme/spkg-configure.m4 create mode 100644 build/pkgs/hatch_vcs/distros/alpine.txt create mode 100644 build/pkgs/hatch_vcs/distros/arch.txt create mode 100644 build/pkgs/hatch_vcs/distros/debian.txt create mode 100644 build/pkgs/hatch_vcs/distros/fedora.txt create mode 100644 build/pkgs/hatch_vcs/distros/freebsd.txt create mode 100644 build/pkgs/hatch_vcs/distros/gentoo.txt create mode 100644 build/pkgs/hatch_vcs/distros/macports.txt create mode 100644 build/pkgs/hatch_vcs/distros/opensuse.txt create mode 100644 build/pkgs/hatch_vcs/distros/void.txt create mode 100644 build/pkgs/hatch_vcs/spkg-configure.m4 create mode 100644 build/pkgs/trove_classifiers/distros/alpine.txt create mode 100644 build/pkgs/trove_classifiers/distros/arch.txt create mode 100644 build/pkgs/trove_classifiers/distros/fedora.txt create mode 100644 build/pkgs/trove_classifiers/distros/freebsd.txt create mode 100644 build/pkgs/trove_classifiers/distros/gentoo.txt create mode 100644 build/pkgs/trove_classifiers/distros/macports.txt create mode 100644 build/pkgs/trove_classifiers/spkg-configure.m4 diff --git a/build/pkgs/calver/distros/alpine.txt b/build/pkgs/calver/distros/alpine.txt new file mode 100644 index 00000000000..8255792e691 --- /dev/null +++ b/build/pkgs/calver/distros/alpine.txt @@ -0,0 +1 @@ +py3-calver diff --git a/build/pkgs/calver/distros/arch.txt b/build/pkgs/calver/distros/arch.txt new file mode 100644 index 00000000000..d55fc26d242 --- /dev/null +++ b/build/pkgs/calver/distros/arch.txt @@ -0,0 +1 @@ +python-calver diff --git a/build/pkgs/calver/distros/freebsd.txt b/build/pkgs/calver/distros/freebsd.txt new file mode 100644 index 00000000000..de235fba4a8 --- /dev/null +++ b/build/pkgs/calver/distros/freebsd.txt @@ -0,0 +1 @@ +devel/py-calver diff --git a/build/pkgs/calver/distros/gentoo.txt b/build/pkgs/calver/distros/gentoo.txt new file mode 100644 index 00000000000..62948b78bc0 --- /dev/null +++ b/build/pkgs/calver/distros/gentoo.txt @@ -0,0 +1 @@ +calver diff --git a/build/pkgs/calver/distros/install-requires.txt b/build/pkgs/calver/distros/install-requires.txt new file mode 100644 index 00000000000..62948b78bc0 --- /dev/null +++ b/build/pkgs/calver/distros/install-requires.txt @@ -0,0 +1 @@ +calver diff --git a/build/pkgs/calver/distros/macports.txt b/build/pkgs/calver/distros/macports.txt new file mode 100644 index 00000000000..69e97601935 --- /dev/null +++ b/build/pkgs/calver/distros/macports.txt @@ -0,0 +1 @@ +py-calver diff --git a/build/pkgs/calver/distros/opensuse.txt b/build/pkgs/calver/distros/opensuse.txt new file mode 100644 index 00000000000..d55fc26d242 --- /dev/null +++ b/build/pkgs/calver/distros/opensuse.txt @@ -0,0 +1 @@ +python-calver diff --git a/build/pkgs/calver/distros/package-version.txt b/build/pkgs/calver/distros/package-version.txt new file mode 100644 index 00000000000..42376d1100a --- /dev/null +++ b/build/pkgs/calver/distros/package-version.txt @@ -0,0 +1 @@ +2022.6.26 diff --git a/build/pkgs/calver/distros/void.txt b/build/pkgs/calver/distros/void.txt new file mode 100644 index 00000000000..f26512ac1ec --- /dev/null +++ b/build/pkgs/calver/distros/void.txt @@ -0,0 +1 @@ +python3-calver diff --git a/build/pkgs/calver/spkg-configure.m4 b/build/pkgs/calver/spkg-configure.m4 new file mode 100644 index 00000000000..8b3e503802c --- /dev/null +++ b/build/pkgs/calver/spkg-configure.m4 @@ -0,0 +1,3 @@ +SAGE_SPKG_CONFIGURE([calver], [ + SAGE_PYTHON_PACKAGE_CHECK([calver]) +]) diff --git a/build/pkgs/fastjsonschema/distros/alpine.txt b/build/pkgs/fastjsonschema/distros/alpine.txt new file mode 100644 index 00000000000..6bc734d2640 --- /dev/null +++ b/build/pkgs/fastjsonschema/distros/alpine.txt @@ -0,0 +1 @@ +py3-fastjsonschema diff --git a/build/pkgs/fastjsonschema/distros/arch.txt b/build/pkgs/fastjsonschema/distros/arch.txt new file mode 100644 index 00000000000..7a8bdf5369b --- /dev/null +++ b/build/pkgs/fastjsonschema/distros/arch.txt @@ -0,0 +1 @@ +python-fastjsonschema diff --git a/build/pkgs/fastjsonschema/distros/debian.txt b/build/pkgs/fastjsonschema/distros/debian.txt new file mode 100644 index 00000000000..7a8bdf5369b --- /dev/null +++ b/build/pkgs/fastjsonschema/distros/debian.txt @@ -0,0 +1 @@ +python-fastjsonschema diff --git a/build/pkgs/fastjsonschema/distros/fedora.txt b/build/pkgs/fastjsonschema/distros/fedora.txt new file mode 100644 index 00000000000..7a8bdf5369b --- /dev/null +++ b/build/pkgs/fastjsonschema/distros/fedora.txt @@ -0,0 +1 @@ +python-fastjsonschema diff --git a/build/pkgs/fastjsonschema/distros/freebsd.txt b/build/pkgs/fastjsonschema/distros/freebsd.txt new file mode 100644 index 00000000000..cd3d138fdea --- /dev/null +++ b/build/pkgs/fastjsonschema/distros/freebsd.txt @@ -0,0 +1 @@ +devel/py-fastjsonschema diff --git a/build/pkgs/fastjsonschema/distros/gentoo.txt b/build/pkgs/fastjsonschema/distros/gentoo.txt new file mode 100644 index 00000000000..1c7b95ab7a7 --- /dev/null +++ b/build/pkgs/fastjsonschema/distros/gentoo.txt @@ -0,0 +1 @@ +dev-python/fastjsonschema diff --git a/build/pkgs/fastjsonschema/distros/macports.txt b/build/pkgs/fastjsonschema/distros/macports.txt new file mode 100644 index 00000000000..a071757bc5b --- /dev/null +++ b/build/pkgs/fastjsonschema/distros/macports.txt @@ -0,0 +1 @@ +py-fastjsonschema diff --git a/build/pkgs/fastjsonschema/distros/opensuse.txt b/build/pkgs/fastjsonschema/distros/opensuse.txt new file mode 100644 index 00000000000..7a8bdf5369b --- /dev/null +++ b/build/pkgs/fastjsonschema/distros/opensuse.txt @@ -0,0 +1 @@ +python-fastjsonschema diff --git a/build/pkgs/fastjsonschema/distros/void.txt b/build/pkgs/fastjsonschema/distros/void.txt new file mode 100644 index 00000000000..aba120db917 --- /dev/null +++ b/build/pkgs/fastjsonschema/distros/void.txt @@ -0,0 +1 @@ +python3-fastjsonschema diff --git a/build/pkgs/fastjsonschema/spkg-configure.m4 b/build/pkgs/fastjsonschema/spkg-configure.m4 new file mode 100644 index 00000000000..944aeddbfaf --- /dev/null +++ b/build/pkgs/fastjsonschema/spkg-configure.m4 @@ -0,0 +1,3 @@ +SAGE_SPKG_CONFIGURE([fastjsonschema], [ + SAGE_PYTHON_PACKAGE_CHECK([fastjsonschema]) +]) diff --git a/build/pkgs/hatch_fancy_pypi_readme/distros/alpine.txt b/build/pkgs/hatch_fancy_pypi_readme/distros/alpine.txt new file mode 100644 index 00000000000..0046a6941d0 --- /dev/null +++ b/build/pkgs/hatch_fancy_pypi_readme/distros/alpine.txt @@ -0,0 +1 @@ +py3-hatch-fancy-pypi-readme diff --git a/build/pkgs/hatch_fancy_pypi_readme/distros/arch.txt b/build/pkgs/hatch_fancy_pypi_readme/distros/arch.txt new file mode 100644 index 00000000000..7df4edcccd3 --- /dev/null +++ b/build/pkgs/hatch_fancy_pypi_readme/distros/arch.txt @@ -0,0 +1 @@ +python-hatch-fancy-pypi-readme diff --git a/build/pkgs/hatch_fancy_pypi_readme/distros/debian.txt b/build/pkgs/hatch_fancy_pypi_readme/distros/debian.txt new file mode 100644 index 00000000000..7df4edcccd3 --- /dev/null +++ b/build/pkgs/hatch_fancy_pypi_readme/distros/debian.txt @@ -0,0 +1 @@ +python-hatch-fancy-pypi-readme diff --git a/build/pkgs/hatch_fancy_pypi_readme/distros/fedora.txt b/build/pkgs/hatch_fancy_pypi_readme/distros/fedora.txt new file mode 100644 index 00000000000..7df4edcccd3 --- /dev/null +++ b/build/pkgs/hatch_fancy_pypi_readme/distros/fedora.txt @@ -0,0 +1 @@ +python-hatch-fancy-pypi-readme diff --git a/build/pkgs/hatch_fancy_pypi_readme/distros/freebsd.txt b/build/pkgs/hatch_fancy_pypi_readme/distros/freebsd.txt new file mode 100644 index 00000000000..b3e8d47dc5a --- /dev/null +++ b/build/pkgs/hatch_fancy_pypi_readme/distros/freebsd.txt @@ -0,0 +1 @@ +devel/py-hatch-fancy-pypi-readme diff --git a/build/pkgs/hatch_fancy_pypi_readme/distros/gentoo.txt b/build/pkgs/hatch_fancy_pypi_readme/distros/gentoo.txt new file mode 100644 index 00000000000..88ad9653448 --- /dev/null +++ b/build/pkgs/hatch_fancy_pypi_readme/distros/gentoo.txt @@ -0,0 +1 @@ +dev-python/hatch-fancy-pypi-readme diff --git a/build/pkgs/hatch_fancy_pypi_readme/distros/macports.txt b/build/pkgs/hatch_fancy_pypi_readme/distros/macports.txt new file mode 100644 index 00000000000..442557c9f7f --- /dev/null +++ b/build/pkgs/hatch_fancy_pypi_readme/distros/macports.txt @@ -0,0 +1 @@ +py-hatch-fancy-pypi-readme diff --git a/build/pkgs/hatch_fancy_pypi_readme/distros/opensuse.txt b/build/pkgs/hatch_fancy_pypi_readme/distros/opensuse.txt new file mode 100644 index 00000000000..7df4edcccd3 --- /dev/null +++ b/build/pkgs/hatch_fancy_pypi_readme/distros/opensuse.txt @@ -0,0 +1 @@ +python-hatch-fancy-pypi-readme diff --git a/build/pkgs/hatch_fancy_pypi_readme/spkg-configure.m4 b/build/pkgs/hatch_fancy_pypi_readme/spkg-configure.m4 new file mode 100644 index 00000000000..864f889676d --- /dev/null +++ b/build/pkgs/hatch_fancy_pypi_readme/spkg-configure.m4 @@ -0,0 +1,3 @@ +SAGE_SPKG_CONFIGURE([hatch_fancy_pypi_readme], [ + SAGE_PYTHON_PACKAGE_CHECK([hatch_fancy_pypi_readme]) +]) diff --git a/build/pkgs/hatch_vcs/distros/alpine.txt b/build/pkgs/hatch_vcs/distros/alpine.txt new file mode 100644 index 00000000000..f83237884b5 --- /dev/null +++ b/build/pkgs/hatch_vcs/distros/alpine.txt @@ -0,0 +1 @@ +py3-hatch-vcs diff --git a/build/pkgs/hatch_vcs/distros/arch.txt b/build/pkgs/hatch_vcs/distros/arch.txt new file mode 100644 index 00000000000..8441f14bba2 --- /dev/null +++ b/build/pkgs/hatch_vcs/distros/arch.txt @@ -0,0 +1 @@ +python-hatch-vcs diff --git a/build/pkgs/hatch_vcs/distros/debian.txt b/build/pkgs/hatch_vcs/distros/debian.txt new file mode 100644 index 00000000000..04e2069fbb3 --- /dev/null +++ b/build/pkgs/hatch_vcs/distros/debian.txt @@ -0,0 +1 @@ +hatch-vcs diff --git a/build/pkgs/hatch_vcs/distros/fedora.txt b/build/pkgs/hatch_vcs/distros/fedora.txt new file mode 100644 index 00000000000..8441f14bba2 --- /dev/null +++ b/build/pkgs/hatch_vcs/distros/fedora.txt @@ -0,0 +1 @@ +python-hatch-vcs diff --git a/build/pkgs/hatch_vcs/distros/freebsd.txt b/build/pkgs/hatch_vcs/distros/freebsd.txt new file mode 100644 index 00000000000..53c6f650d58 --- /dev/null +++ b/build/pkgs/hatch_vcs/distros/freebsd.txt @@ -0,0 +1 @@ +devel/py-hatch-vcs diff --git a/build/pkgs/hatch_vcs/distros/gentoo.txt b/build/pkgs/hatch_vcs/distros/gentoo.txt new file mode 100644 index 00000000000..ad6e0d96197 --- /dev/null +++ b/build/pkgs/hatch_vcs/distros/gentoo.txt @@ -0,0 +1 @@ +dev-python/hatch-vcs diff --git a/build/pkgs/hatch_vcs/distros/macports.txt b/build/pkgs/hatch_vcs/distros/macports.txt new file mode 100644 index 00000000000..cdccfd5952e --- /dev/null +++ b/build/pkgs/hatch_vcs/distros/macports.txt @@ -0,0 +1 @@ +py-hatch-vcs diff --git a/build/pkgs/hatch_vcs/distros/opensuse.txt b/build/pkgs/hatch_vcs/distros/opensuse.txt new file mode 100644 index 00000000000..cb34dc58d71 --- /dev/null +++ b/build/pkgs/hatch_vcs/distros/opensuse.txt @@ -0,0 +1 @@ +python-hatch_vcs diff --git a/build/pkgs/hatch_vcs/distros/void.txt b/build/pkgs/hatch_vcs/distros/void.txt new file mode 100644 index 00000000000..04e2069fbb3 --- /dev/null +++ b/build/pkgs/hatch_vcs/distros/void.txt @@ -0,0 +1 @@ +hatch-vcs diff --git a/build/pkgs/hatch_vcs/spkg-configure.m4 b/build/pkgs/hatch_vcs/spkg-configure.m4 new file mode 100644 index 00000000000..aa5a1c212df --- /dev/null +++ b/build/pkgs/hatch_vcs/spkg-configure.m4 @@ -0,0 +1,3 @@ +SAGE_SPKG_CONFIGURE([hatch_vcs], [ + SAGE_PYTHON_PACKAGE_CHECK([hatch_vcs]) +]) diff --git a/build/pkgs/trove_classifiers/distros/alpine.txt b/build/pkgs/trove_classifiers/distros/alpine.txt new file mode 100644 index 00000000000..432fb829920 --- /dev/null +++ b/build/pkgs/trove_classifiers/distros/alpine.txt @@ -0,0 +1 @@ +py3-trove-classifiers diff --git a/build/pkgs/trove_classifiers/distros/arch.txt b/build/pkgs/trove_classifiers/distros/arch.txt new file mode 100644 index 00000000000..faa3f51e677 --- /dev/null +++ b/build/pkgs/trove_classifiers/distros/arch.txt @@ -0,0 +1 @@ +python-trove-classifiers diff --git a/build/pkgs/trove_classifiers/distros/fedora.txt b/build/pkgs/trove_classifiers/distros/fedora.txt new file mode 100644 index 00000000000..faa3f51e677 --- /dev/null +++ b/build/pkgs/trove_classifiers/distros/fedora.txt @@ -0,0 +1 @@ +python-trove-classifiers diff --git a/build/pkgs/trove_classifiers/distros/freebsd.txt b/build/pkgs/trove_classifiers/distros/freebsd.txt new file mode 100644 index 00000000000..661ffd3cb2f --- /dev/null +++ b/build/pkgs/trove_classifiers/distros/freebsd.txt @@ -0,0 +1 @@ +devel/py-trove-classifiers diff --git a/build/pkgs/trove_classifiers/distros/gentoo.txt b/build/pkgs/trove_classifiers/distros/gentoo.txt new file mode 100644 index 00000000000..5b2a99ef1a2 --- /dev/null +++ b/build/pkgs/trove_classifiers/distros/gentoo.txt @@ -0,0 +1 @@ +dev-python/trove-classifiers diff --git a/build/pkgs/trove_classifiers/distros/macports.txt b/build/pkgs/trove_classifiers/distros/macports.txt new file mode 100644 index 00000000000..01f8c85049e --- /dev/null +++ b/build/pkgs/trove_classifiers/distros/macports.txt @@ -0,0 +1 @@ +py-trove-classifiers diff --git a/build/pkgs/trove_classifiers/spkg-configure.m4 b/build/pkgs/trove_classifiers/spkg-configure.m4 new file mode 100644 index 00000000000..f364bd7b67c --- /dev/null +++ b/build/pkgs/trove_classifiers/spkg-configure.m4 @@ -0,0 +1,3 @@ +SAGE_SPKG_CONFIGURE([trove_classifiers], [ + SAGE_PYTHON_PACKAGE_CHECK([trove_classifiers]) +]) From c259524566ef240296a58b445c95b68dc275cf3f Mon Sep 17 00:00:00 2001 From: Dima Pasechnik Date: Mon, 25 Sep 2023 19:47:23 +0100 Subject: [PATCH 195/216] spkg-configure for cython --- build/pkgs/cython/spkg-configure.m4 | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 build/pkgs/cython/spkg-configure.m4 diff --git a/build/pkgs/cython/spkg-configure.m4 b/build/pkgs/cython/spkg-configure.m4 new file mode 100644 index 00000000000..5e4bfb9aa12 --- /dev/null +++ b/build/pkgs/cython/spkg-configure.m4 @@ -0,0 +1,3 @@ +SAGE_SPKG_CONFIGURE([cython], [ + SAGE_PYTHON_PACKAGE_CHECK([cython]) +]) From aff12df6aa2125dc1be8e5736d0b2eb7f1c8a74b Mon Sep 17 00:00:00 2001 From: Dima Pasechnik Date: Tue, 26 Sep 2023 14:20:59 +0100 Subject: [PATCH 196/216] more spkg-configures and distros info --- build/pkgs/appnope/spkg-configure.m4 | 3 +++ build/pkgs/argon2_cffi_bindings/distros/alpine.txt | 1 + build/pkgs/argon2_cffi_bindings/distros/arch.txt | 1 + build/pkgs/argon2_cffi_bindings/distros/fedora.txt | 1 + build/pkgs/argon2_cffi_bindings/distros/freebsd.txt | 1 + build/pkgs/argon2_cffi_bindings/distros/gentoo.txt | 1 + build/pkgs/argon2_cffi_bindings/distros/macports.txt | 1 + build/pkgs/argon2_cffi_bindings/distros/opensuse.txt | 1 + build/pkgs/argon2_cffi_bindings/spkg-configure.m4 | 3 +++ build/pkgs/hatch_nodejs_version/distros/alpine.txt | 1 + build/pkgs/hatch_nodejs_version/distros/arch.txt | 1 + build/pkgs/hatch_nodejs_version/distros/debian.txt | 1 + build/pkgs/hatch_nodejs_version/distros/freebsd.txt | 1 + build/pkgs/hatch_nodejs_version/distros/opensuse.txt | 1 + build/pkgs/hatch_nodejs_version/spkg-configure.m4 | 3 +++ 15 files changed, 21 insertions(+) create mode 100644 build/pkgs/appnope/spkg-configure.m4 create mode 100644 build/pkgs/argon2_cffi_bindings/distros/alpine.txt create mode 100644 build/pkgs/argon2_cffi_bindings/distros/arch.txt create mode 100644 build/pkgs/argon2_cffi_bindings/distros/fedora.txt create mode 100644 build/pkgs/argon2_cffi_bindings/distros/freebsd.txt create mode 100644 build/pkgs/argon2_cffi_bindings/distros/gentoo.txt create mode 100644 build/pkgs/argon2_cffi_bindings/distros/macports.txt create mode 100644 build/pkgs/argon2_cffi_bindings/distros/opensuse.txt create mode 100644 build/pkgs/argon2_cffi_bindings/spkg-configure.m4 create mode 100644 build/pkgs/hatch_nodejs_version/distros/alpine.txt create mode 100644 build/pkgs/hatch_nodejs_version/distros/arch.txt create mode 100644 build/pkgs/hatch_nodejs_version/distros/debian.txt create mode 100644 build/pkgs/hatch_nodejs_version/distros/freebsd.txt create mode 100644 build/pkgs/hatch_nodejs_version/distros/opensuse.txt create mode 100644 build/pkgs/hatch_nodejs_version/spkg-configure.m4 diff --git a/build/pkgs/appnope/spkg-configure.m4 b/build/pkgs/appnope/spkg-configure.m4 new file mode 100644 index 00000000000..059e63eb4fd --- /dev/null +++ b/build/pkgs/appnope/spkg-configure.m4 @@ -0,0 +1,3 @@ +SAGE_SPKG_CONFIGURE([appnope], [ + SAGE_PYTHON_PACKAGE_CHECK([appnope]) +]) diff --git a/build/pkgs/argon2_cffi_bindings/distros/alpine.txt b/build/pkgs/argon2_cffi_bindings/distros/alpine.txt new file mode 100644 index 00000000000..ae49cefff4e --- /dev/null +++ b/build/pkgs/argon2_cffi_bindings/distros/alpine.txt @@ -0,0 +1 @@ +py3-argon2-cffi-bindings diff --git a/build/pkgs/argon2_cffi_bindings/distros/arch.txt b/build/pkgs/argon2_cffi_bindings/distros/arch.txt new file mode 100644 index 00000000000..9da9b3cf29a --- /dev/null +++ b/build/pkgs/argon2_cffi_bindings/distros/arch.txt @@ -0,0 +1 @@ +python-argon2-cffi-bindings diff --git a/build/pkgs/argon2_cffi_bindings/distros/fedora.txt b/build/pkgs/argon2_cffi_bindings/distros/fedora.txt new file mode 100644 index 00000000000..9da9b3cf29a --- /dev/null +++ b/build/pkgs/argon2_cffi_bindings/distros/fedora.txt @@ -0,0 +1 @@ +python-argon2-cffi-bindings diff --git a/build/pkgs/argon2_cffi_bindings/distros/freebsd.txt b/build/pkgs/argon2_cffi_bindings/distros/freebsd.txt new file mode 100644 index 00000000000..70621e55ccc --- /dev/null +++ b/build/pkgs/argon2_cffi_bindings/distros/freebsd.txt @@ -0,0 +1 @@ +security/py-argon2-cffi-bindings diff --git a/build/pkgs/argon2_cffi_bindings/distros/gentoo.txt b/build/pkgs/argon2_cffi_bindings/distros/gentoo.txt new file mode 100644 index 00000000000..8a1d2c01312 --- /dev/null +++ b/build/pkgs/argon2_cffi_bindings/distros/gentoo.txt @@ -0,0 +1 @@ +dev-python/argon2-cffi-bindings diff --git a/build/pkgs/argon2_cffi_bindings/distros/macports.txt b/build/pkgs/argon2_cffi_bindings/distros/macports.txt new file mode 100644 index 00000000000..42e046a898d --- /dev/null +++ b/build/pkgs/argon2_cffi_bindings/distros/macports.txt @@ -0,0 +1 @@ +py-argon2-cffi-bindings diff --git a/build/pkgs/argon2_cffi_bindings/distros/opensuse.txt b/build/pkgs/argon2_cffi_bindings/distros/opensuse.txt new file mode 100644 index 00000000000..9da9b3cf29a --- /dev/null +++ b/build/pkgs/argon2_cffi_bindings/distros/opensuse.txt @@ -0,0 +1 @@ +python-argon2-cffi-bindings diff --git a/build/pkgs/argon2_cffi_bindings/spkg-configure.m4 b/build/pkgs/argon2_cffi_bindings/spkg-configure.m4 new file mode 100644 index 00000000000..e0c637d0757 --- /dev/null +++ b/build/pkgs/argon2_cffi_bindings/spkg-configure.m4 @@ -0,0 +1,3 @@ +SAGE_SPKG_CONFIGURE([argon2_cffi_bindings], [ + SAGE_PYTHON_PACKAGE_CHECK([argon2_cffi_bindings]) +]) diff --git a/build/pkgs/hatch_nodejs_version/distros/alpine.txt b/build/pkgs/hatch_nodejs_version/distros/alpine.txt new file mode 100644 index 00000000000..6e393cf297b --- /dev/null +++ b/build/pkgs/hatch_nodejs_version/distros/alpine.txt @@ -0,0 +1 @@ +py3-hatch-nodejs-version diff --git a/build/pkgs/hatch_nodejs_version/distros/arch.txt b/build/pkgs/hatch_nodejs_version/distros/arch.txt new file mode 100644 index 00000000000..e045ff5442e --- /dev/null +++ b/build/pkgs/hatch_nodejs_version/distros/arch.txt @@ -0,0 +1 @@ +python-hatch-nodejs-version diff --git a/build/pkgs/hatch_nodejs_version/distros/debian.txt b/build/pkgs/hatch_nodejs_version/distros/debian.txt new file mode 100644 index 00000000000..e045ff5442e --- /dev/null +++ b/build/pkgs/hatch_nodejs_version/distros/debian.txt @@ -0,0 +1 @@ +python-hatch-nodejs-version diff --git a/build/pkgs/hatch_nodejs_version/distros/freebsd.txt b/build/pkgs/hatch_nodejs_version/distros/freebsd.txt new file mode 100644 index 00000000000..83177ce5196 --- /dev/null +++ b/build/pkgs/hatch_nodejs_version/distros/freebsd.txt @@ -0,0 +1 @@ +devel/py-hatch-nodejs-version diff --git a/build/pkgs/hatch_nodejs_version/distros/opensuse.txt b/build/pkgs/hatch_nodejs_version/distros/opensuse.txt new file mode 100644 index 00000000000..439415283d6 --- /dev/null +++ b/build/pkgs/hatch_nodejs_version/distros/opensuse.txt @@ -0,0 +1 @@ +python-hatch_nodejs_version diff --git a/build/pkgs/hatch_nodejs_version/spkg-configure.m4 b/build/pkgs/hatch_nodejs_version/spkg-configure.m4 new file mode 100644 index 00000000000..bc1b2c772cb --- /dev/null +++ b/build/pkgs/hatch_nodejs_version/spkg-configure.m4 @@ -0,0 +1,3 @@ +SAGE_SPKG_CONFIGURE([hatch_nodejs_version], [ + SAGE_PYTHON_PACKAGE_CHECK([hatch_nodejs_version]) +]) From 0df6885ba69e39b924e3c2f01c9e2d22a1b55220 Mon Sep 17 00:00:00 2001 From: Dima Pasechnik Date: Thu, 28 Sep 2023 22:35:17 +0100 Subject: [PATCH 197/216] leave hatch_nodejs_version intact, in preparation for its removal --- build/pkgs/hatch_nodejs_version/distros/alpine.txt | 1 - build/pkgs/hatch_nodejs_version/distros/arch.txt | 1 - build/pkgs/hatch_nodejs_version/distros/debian.txt | 1 - build/pkgs/hatch_nodejs_version/distros/freebsd.txt | 1 - build/pkgs/hatch_nodejs_version/distros/opensuse.txt | 1 - build/pkgs/hatch_nodejs_version/spkg-configure.m4 | 3 --- 6 files changed, 8 deletions(-) delete mode 100644 build/pkgs/hatch_nodejs_version/distros/alpine.txt delete mode 100644 build/pkgs/hatch_nodejs_version/distros/arch.txt delete mode 100644 build/pkgs/hatch_nodejs_version/distros/debian.txt delete mode 100644 build/pkgs/hatch_nodejs_version/distros/freebsd.txt delete mode 100644 build/pkgs/hatch_nodejs_version/distros/opensuse.txt delete mode 100644 build/pkgs/hatch_nodejs_version/spkg-configure.m4 diff --git a/build/pkgs/hatch_nodejs_version/distros/alpine.txt b/build/pkgs/hatch_nodejs_version/distros/alpine.txt deleted file mode 100644 index 6e393cf297b..00000000000 --- a/build/pkgs/hatch_nodejs_version/distros/alpine.txt +++ /dev/null @@ -1 +0,0 @@ -py3-hatch-nodejs-version diff --git a/build/pkgs/hatch_nodejs_version/distros/arch.txt b/build/pkgs/hatch_nodejs_version/distros/arch.txt deleted file mode 100644 index e045ff5442e..00000000000 --- a/build/pkgs/hatch_nodejs_version/distros/arch.txt +++ /dev/null @@ -1 +0,0 @@ -python-hatch-nodejs-version diff --git a/build/pkgs/hatch_nodejs_version/distros/debian.txt b/build/pkgs/hatch_nodejs_version/distros/debian.txt deleted file mode 100644 index e045ff5442e..00000000000 --- a/build/pkgs/hatch_nodejs_version/distros/debian.txt +++ /dev/null @@ -1 +0,0 @@ -python-hatch-nodejs-version diff --git a/build/pkgs/hatch_nodejs_version/distros/freebsd.txt b/build/pkgs/hatch_nodejs_version/distros/freebsd.txt deleted file mode 100644 index 83177ce5196..00000000000 --- a/build/pkgs/hatch_nodejs_version/distros/freebsd.txt +++ /dev/null @@ -1 +0,0 @@ -devel/py-hatch-nodejs-version diff --git a/build/pkgs/hatch_nodejs_version/distros/opensuse.txt b/build/pkgs/hatch_nodejs_version/distros/opensuse.txt deleted file mode 100644 index 439415283d6..00000000000 --- a/build/pkgs/hatch_nodejs_version/distros/opensuse.txt +++ /dev/null @@ -1 +0,0 @@ -python-hatch_nodejs_version diff --git a/build/pkgs/hatch_nodejs_version/spkg-configure.m4 b/build/pkgs/hatch_nodejs_version/spkg-configure.m4 deleted file mode 100644 index bc1b2c772cb..00000000000 --- a/build/pkgs/hatch_nodejs_version/spkg-configure.m4 +++ /dev/null @@ -1,3 +0,0 @@ -SAGE_SPKG_CONFIGURE([hatch_nodejs_version], [ - SAGE_PYTHON_PACKAGE_CHECK([hatch_nodejs_version]) -]) From a9c3665f8acd802e249f8e94a39fb30f0ea98e29 Mon Sep 17 00:00:00 2001 From: Dima Pasechnik Date: Sat, 30 Sep 2023 23:45:14 +0100 Subject: [PATCH 198/216] adjust gentoo package name --- build/pkgs/stack_data/distros/gentoo.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/pkgs/stack_data/distros/gentoo.txt b/build/pkgs/stack_data/distros/gentoo.txt index 6f94c8c7fdc..88d042a3231 100644 --- a/build/pkgs/stack_data/distros/gentoo.txt +++ b/build/pkgs/stack_data/distros/gentoo.txt @@ -1 +1 @@ -dev-python/stack_data +dev-python/stack-data From 7c7ba0447ec9cc0b588e05835c729d9499e69846 Mon Sep 17 00:00:00 2001 From: Dima Pasechnik Date: Mon, 2 Oct 2023 16:15:53 +0100 Subject: [PATCH 199/216] remove an extra copy --- build/pkgs/calver/distros/install-requires.txt | 1 - 1 file changed, 1 deletion(-) delete mode 100644 build/pkgs/calver/distros/install-requires.txt diff --git a/build/pkgs/calver/distros/install-requires.txt b/build/pkgs/calver/distros/install-requires.txt deleted file mode 100644 index 62948b78bc0..00000000000 --- a/build/pkgs/calver/distros/install-requires.txt +++ /dev/null @@ -1 +0,0 @@ -calver From 27e037f0e98f4703830413b34656451aa78f8502 Mon Sep 17 00:00:00 2001 From: Dima Pasechnik Date: Tue, 10 Oct 2023 14:30:37 +0100 Subject: [PATCH 200/216] allows system cython packages to work --- build/pkgs/cython/patches/5690.patch | 48 ++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 build/pkgs/cython/patches/5690.patch diff --git a/build/pkgs/cython/patches/5690.patch b/build/pkgs/cython/patches/5690.patch new file mode 100644 index 00000000000..cc927879e1f --- /dev/null +++ b/build/pkgs/cython/patches/5690.patch @@ -0,0 +1,48 @@ +diff --git a/Cython/Debugger/DebugWriter.py b/Cython/Debugger/DebugWriter.py +index 8b1fb75b027..2c3c310fc64 100644 +--- a/Cython/Debugger/DebugWriter.py ++++ b/Cython/Debugger/DebugWriter.py +@@ -18,6 +18,21 @@ + etree = None + + from ..Compiler import Errors ++from ..Compiler.StringEncoding import EncodedString ++ ++ ++def is_valid_tag(name): ++ """ ++ Names like '.0' are used internally for arguments ++ to functions creating generator expressions, ++ however they are not identifiers. ++ ++ See https://github.com/cython/cython/issues/5552 ++ """ ++ if isinstance(name, EncodedString): ++ if name.startswith(".") and name[1:].isdecimal(): ++ return False ++ return True + + + class CythonDebugWriter(object): +@@ -39,14 +54,17 @@ def __init__(self, output_dir): + self.start('cython_debug', attrs=dict(version='1.0')) + + def start(self, name, attrs=None): +- self.tb.start(name, attrs or {}) ++ if is_valid_tag(name): ++ self.tb.start(name, attrs or {}) + + def end(self, name): +- self.tb.end(name) ++ if is_valid_tag(name): ++ self.tb.end(name) + + def add_entry(self, name, **attrs): +- self.tb.start(name, attrs) +- self.tb.end(name) ++ if is_valid_tag(name): ++ self.tb.start(name, attrs) ++ self.tb.end(name) + + def serialize(self): + self.tb.end('Module') From 042eb5215373093fcdb27683464422b5968b0d32 Mon Sep 17 00:00:00 2001 From: dcoudert Date: Sun, 15 Oct 2023 17:54:54 +0200 Subject: [PATCH 201/216] fix doctest in posets --- src/sage/combinat/posets/posets.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/combinat/posets/posets.py b/src/sage/combinat/posets/posets.py index d3c46a1daf7..ac9caac64be 100644 --- a/src/sage/combinat/posets/posets.py +++ b/src/sage/combinat/posets/posets.py @@ -1374,8 +1374,8 @@ def _latex_(self): sage: print(P._latex_()) # optional - dot2tex graphviz \begin{tikzpicture}[>=latex,line join=bevel,] %% - \node (node_...) at (5...bp,...bp) [draw,draw=none] {$...$}; - \node (node_...) at (5...bp,...bp) [draw,draw=none] {$...$}; + \node (node_...) at (...bp,...bp) [draw,draw=none] {$...$}; + \node (node_...) at (...bp,...bp) [draw,draw=none] {$...$}; \draw [black,->] (node_...) ..controls (...bp,...bp) and (...bp,...bp) .. (node_...); % \end{tikzpicture} From 5924072a0d59fcf5e5fe51587dc1dc7855a15dd2 Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Mon, 16 Oct 2023 01:49:29 +0000 Subject: [PATCH 202/216] Combine ci linter jobs --- .github/workflows/lint.yml | 54 +++++++++----------------------------- 1 file changed, 13 insertions(+), 41 deletions(-) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 79ca26827b1..afd0406341c 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -14,60 +14,32 @@ concurrency: cancel-in-progress: true jobs: - lint-pycodestyle: - name: Code style check with pycodestyle + lint: + name: Lint runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v4 + - name: Merge CI fixes from sagemath/sage run: | .ci/merge-fixes.sh env: GH_TOKEN: ${{ github.token }} + - name: Set up Python uses: actions/setup-python@v4 with: python-version: 3.9 - - name: Install pycodestyle - run: pip install tox pycodestyle - - name: Lint using pycodestyle + + - name: Install dependencies + run: pip install tox pycodestyle relint + + - name: Code style check with pycodestyle run: tox -e pycodestyle-minimal - lint-relint: - name: Code style check with relint - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v4 - - name: Merge CI fixes from sagemath/sage - run: | - .ci/merge-fixes.sh - env: - GH_TOKEN: ${{ github.token }} - - name: Set up Python - uses: actions/setup-python@v4 - with: - python-version: 3.9 - - name: Install relint - run: pip install tox relint - - name: Lint using relint + + - name: Code style check with relint run: tox -e relint -- src/sage/ - lint-rst: - name: Validate docstring markup as RST - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v4 - - name: Merge CI fixes from sagemath/sage - run: | - .ci/merge-fixes.sh - env: - GH_TOKEN: ${{ github.token }} - - name: Set up Python - uses: actions/setup-python@v4 - with: - python-version: 3.9 - - name: Install tox - run: pip install tox - - name: Lint using tox -e rst + + - name: Validate docstring markup as RST run: tox -e rst From e1ed761eb24d0f4bc261cac8f364a00ff8ae864a Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Mon, 16 Oct 2023 02:09:47 +0000 Subject: [PATCH 203/216] Fix mamba install in conda ci workflow --- .github/workflows/ci-conda.yml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/.github/workflows/ci-conda.yml b/.github/workflows/ci-conda.yml index e520fa17104..25984a5e77a 100644 --- a/.github/workflows/ci-conda.yml +++ b/.github/workflows/ci-conda.yml @@ -61,7 +61,22 @@ jobs: key: ${{ runner.os }}-conda-${{ hashFiles('src/environment-3.11.yml') }} + # Mamba currently has problems with dependencies installed from other channels + # https://github.com/libarchive/libarchive/issues/1857 + # https://github.com/conda-incubator/setup-miniconda/issues/292 + # As temporary workaround we move all preinstalled packages over to conda-forge before installing mamba - name: Setup Conda + uses: conda-incubator/setup-miniconda@v2 + with: + python-version: ${{ matrix.python }} + channels: conda-forge + channel-priority: true + + - name: Fix mamba + run: | + conda upgrade --strict-channel-priority -c conda-forge --all + + - name: Setup Conda environment uses: conda-incubator/setup-miniconda@v2 with: python-version: ${{ matrix.python }} From ac443118cceda074b6ac3e31caf045e5bd869e40 Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Mon, 16 Oct 2023 02:20:39 +0000 Subject: [PATCH 204/216] install mamba manually --- .github/workflows/ci-conda.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci-conda.yml b/.github/workflows/ci-conda.yml index 25984a5e77a..432a76e1277 100644 --- a/.github/workflows/ci-conda.yml +++ b/.github/workflows/ci-conda.yml @@ -75,12 +75,13 @@ jobs: - name: Fix mamba run: | conda upgrade --strict-channel-priority -c conda-forge --all + conda install -c conda-forge mamba - name: Setup Conda environment uses: conda-incubator/setup-miniconda@v2 with: python-version: ${{ matrix.python }} - mamba-version: "*" + #mamba-version: "*" channels: conda-forge,defaults channel-priority: true activate-environment: sage From 048ed902b97b80221cce06284adc5716d3b93975 Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Mon, 16 Oct 2023 02:21:31 +0000 Subject: [PATCH 205/216] restrict channel to conda-forge --- .github/workflows/ci-conda.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci-conda.yml b/.github/workflows/ci-conda.yml index 432a76e1277..e9e9ef2ab50 100644 --- a/.github/workflows/ci-conda.yml +++ b/.github/workflows/ci-conda.yml @@ -82,7 +82,7 @@ jobs: with: python-version: ${{ matrix.python }} #mamba-version: "*" - channels: conda-forge,defaults + channels: conda-forge channel-priority: true activate-environment: sage environment-file: src/${{ matrix.conda-env }}-${{ matrix.python }}.yml From 338b668c819e8560669399e2bfe55f81ae7053c1 Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Mon, 16 Oct 2023 02:22:37 +0000 Subject: [PATCH 206/216] use mamba switch --- .github/workflows/ci-conda.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ci-conda.yml b/.github/workflows/ci-conda.yml index e9e9ef2ab50..1265e7611a6 100644 --- a/.github/workflows/ci-conda.yml +++ b/.github/workflows/ci-conda.yml @@ -82,6 +82,7 @@ jobs: with: python-version: ${{ matrix.python }} #mamba-version: "*" + use-mamba: true channels: conda-forge channel-priority: true activate-environment: sage From edbb8a7a27769088f38f2e0cb6af2f499ea05608 Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Mon, 16 Oct 2023 05:37:06 +0000 Subject: [PATCH 207/216] try with miniforge --- .github/workflows/ci-conda.yml | 30 +----------------------------- 1 file changed, 1 insertion(+), 29 deletions(-) diff --git a/.github/workflows/ci-conda.yml b/.github/workflows/ci-conda.yml index 1265e7611a6..aaee77e5be3 100644 --- a/.github/workflows/ci-conda.yml +++ b/.github/workflows/ci-conda.yml @@ -39,18 +39,6 @@ jobs: env: GH_TOKEN: ${{ github.token }} - - name: Check for Miniconda - id: check_conda - run: echo ::set-output name=installed::$CONDA - - # Miniconda is installed by default in the ubuntu-latest, however not in the act-image to run it locally - - name: Install Miniconda - if: steps.check_conda.outputs.installed == '' - run: | - wget https://repo.anaconda.com/miniconda/Miniconda3-py39_4.10.3-Linux-x86_64.sh -O ~/miniconda.sh - bash ~/miniconda.sh -b -p $HOME/miniconda - echo "CONDA=$HOME/miniconda" >> $GITHUB_ENV - - name: Create conda environment files run: ./bootstrap-conda @@ -61,27 +49,11 @@ jobs: key: ${{ runner.os }}-conda-${{ hashFiles('src/environment-3.11.yml') }} - # Mamba currently has problems with dependencies installed from other channels - # https://github.com/libarchive/libarchive/issues/1857 - # https://github.com/conda-incubator/setup-miniconda/issues/292 - # As temporary workaround we move all preinstalled packages over to conda-forge before installing mamba - - name: Setup Conda - uses: conda-incubator/setup-miniconda@v2 - with: - python-version: ${{ matrix.python }} - channels: conda-forge - channel-priority: true - - - name: Fix mamba - run: | - conda upgrade --strict-channel-priority -c conda-forge --all - conda install -c conda-forge mamba - - name: Setup Conda environment uses: conda-incubator/setup-miniconda@v2 with: python-version: ${{ matrix.python }} - #mamba-version: "*" + miniforge-version: latest use-mamba: true channels: conda-forge channel-priority: true From cce709cc19ef6f5d4ab7b54f6eccf3ec4910b496 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Mon, 16 Oct 2023 14:48:21 +0200 Subject: [PATCH 208/216] refresh macaulay2 interface a little bit --- src/sage/interfaces/macaulay2.py | 418 +++++++++++++++++-------------- 1 file changed, 229 insertions(+), 189 deletions(-) diff --git a/src/sage/interfaces/macaulay2.py b/src/sage/interfaces/macaulay2.py index 1d575b4ff7c..1fd27a72bb3 100644 --- a/src/sage/interfaces/macaulay2.py +++ b/src/sage/interfaces/macaulay2.py @@ -5,7 +5,7 @@ You must have ``Macaulay2`` installed on your computer for this interface to work. Macaulay2 is not included with Sage, - but you can obtain it from https://faculty.math.illinois.edu/Macaulay2/. + but you can obtain it from https://macaulay2.com/. No additional optional Sage packages are required. Sage provides an interface to the Macaulay2 computational algebra @@ -27,60 +27,65 @@ EXAMPLES:: - sage: macaulay2('3/5 + 7/11') # optional - macaulay2 + sage: # optional - macaulay2 + sage: macaulay2('3/5 + 7/11') 68 -- 55 - sage: f = macaulay2('f = i -> i^3') # optional - macaulay2 - sage: f # optional - macaulay2 + sage: f = macaulay2('f = i -> i^3') + sage: f f - sage: f(5) # optional - macaulay2 + sage: f(5) 125 - sage: R = macaulay2('ZZ/5[x,y,z]') # optional - macaulay2 - sage: R # optional - macaulay2 + sage: # optional - macaulay2 + sage: R = macaulay2('ZZ/5[x,y,z]') + sage: R ZZ --[x...z] 5 - sage: x = macaulay2('x') # optional - macaulay2 - sage: y = macaulay2('y') # optional - macaulay2 - sage: (x+y)^5 # optional - macaulay2 + sage: x = macaulay2('x') + sage: y = macaulay2('y') + sage: (x+y)^5 5 5 x + y - sage: parent((x+y)^5) # optional - macaulay2 + sage: parent((x+y)^5) Macaulay2 The name of the variable to which a Macaulay2 element is assigned internally can be passed as an argument. This is useful for types like polynomial rings which acquire that name in Macaulay2:: - sage: R = macaulay2('QQ[x,y,z,w]', 'R') # optional - macaulay2 - sage: R # optional - macaulay2 + sage: # optional - macaulay2 + sage: R = macaulay2('QQ[x,y,z,w]', 'R') + sage: R R - sage: f = macaulay2('x^4 + 2*x*y^3 + x*y^2*w + x*y*z*w + x*y*w^2' # optional - macaulay2 + sage: # optional - macaulay2 + sage: f = macaulay2('x^4 + 2*x*y^3 + x*y^2*w + x*y*z*w + x*y*w^2' ....: '+ 2*x*z*w^2 + y^4 + y^3*w + 2*y^2*z*w + z^4 + w^4') - sage: f # optional - macaulay2 + sage: f 4 3 4 4 2 3 2 2 2 4 x + 2x*y + y + z + x*y w + y w + x*y*z*w + 2y z*w + x*y*w + 2x*z*w + w - sage: g = f * macaulay2('x+y^5') # optional - macaulay2 - sage: print(g.factor()) # optional - macaulay2 + sage: g = f * macaulay2('x+y^5') + sage: print(g.factor()) 4 3 4 4 2 3 2 2 2 4 5 (x + 2x*y + y + z + x*y w + y w + x*y*z*w + 2y z*w + x*y*w + 2x*z*w + w )(y + x) Use :meth:`eval` for explicit control over what is sent to the interpreter. The argument is evaluated in Macaulay2 as is:: - sage: macaulay2.eval('compactMatrixForm') # optional - macaulay2 + sage: # optional - macaulay2 + sage: macaulay2.eval('compactMatrixForm') true - sage: macaulay2.eval('compactMatrixForm = false;') # optional - macaulay2 - sage: macaulay2.eval('matrix {{1, x^2+y}}') # optional - macaulay2 + sage: macaulay2.eval('compactMatrixForm = false;') + sage: macaulay2.eval('matrix {{1, x^2+y}}') | 2 | | 1 x + y | 1 2 Matrix R <--- R - sage: macaulay2.eval('compactMatrixForm = true;') # optional - macaulay2 + sage: macaulay2.eval('compactMatrixForm = true;') AUTHORS: @@ -132,7 +137,7 @@ from sage.structure.global_options import GlobalOptions -def remove_output_labels(s): +def remove_output_labels(s) -> str: r""" Remove output labels of Macaulay2 from a string. @@ -166,9 +171,8 @@ def remove_output_labels(s): matches = [label.match(l) for l in lines if l] if not matches: return s - else: - n = min(m.end() - m.start() for m in matches) - return "\n".join(l[n:] for l in lines) + n = min(m.end() - m.start() for m in matches) + return "\n".join(l[n:] for l in lines) PROMPT = "_EGAS_ : " @@ -215,7 +219,7 @@ def __init__(self, maxread=None, script_subdirectory=None, "lineNumber = 10^9;" # Assignment of internal expect variables. 'sageAssign = (k, v) -> (if not instance(v, Sequence) then use v; k <- v);' - ) + ) command = "%s --no-debug --no-readline --silent -e '%s'" % (command, init_str) Expect.__init__(self, name='macaulay2', @@ -366,20 +370,21 @@ class options(GlobalOptions): EXAMPLES:: - sage: macaulay2.options.after_print = True # optional - macaulay2 - sage: A = macaulay2(matrix([[1, 2], [3, 6]])); A # optional - macaulay2 + sage: # optional - macaulay2 + sage: macaulay2.options.after_print = True + sage: A = macaulay2(matrix([[1, 2], [3, 6]])); A | 1 2 | | 3 6 | 2 2 Matrix ZZ <--- ZZ - sage: A.kernel() # optional - macaulay2 + sage: A.kernel() image | 2 | | -1 | 2 ZZ-module, submodule of ZZ - sage: macaulay2.options.after_print = False # optional - macaulay2 + sage: macaulay2.options.after_print = False """ NAME = 'Macaulay2' module = 'sage.interfaces.macaulay2' @@ -435,17 +440,18 @@ def set(self, var, value): Check that internal expect variables do not acquire their global variable name and that ``use`` is invoked (:trac:`28303`):: - sage: R = macaulay2('QQ[x, y]') # indirect doctest, optional - macaulay2 - sage: R.net() # optional - macaulay2 + sage: # optional - macaulay2 + sage: R = macaulay2('QQ[x, y]') # indirect doctest + sage: R.net() QQ[x...y] - sage: S = R / macaulay2('ideal {x^2 - y}') # optional - macaulay2 - sage: macaulay2.eval('class x === %s' % S.name()) # optional - macaulay2 + sage: S = R / macaulay2('ideal {x^2 - y}') + sage: macaulay2.eval('class x === %s' % S.name()) true """ if re.match(r'sage\d+$', var): cmd = 'sageAssign(symbol %s,(%s));' % (var, value) else: - cmd = '%s=(%s);' % (var,value) + cmd = '%s=(%s);' % (var, value) ans = Expect.eval(self, cmd, strip=False) if ans.find("stdio:") != -1: raise RuntimeError("Error evaluating Macaulay2 code.\nIN:%s\nOUT:%s" % (cmd, ans)) @@ -459,11 +465,12 @@ def clear(self, var): EXAMPLES:: - sage: macaulay2.eval('R = QQ[x,y];') # optional - macaulay2 - sage: macaulay2.eval('net class R') # optional - macaulay2 + sage: # optional - macaulay2 + sage: macaulay2.eval('R = QQ[x,y];') + sage: macaulay2.eval('net class R') PolynomialRing - sage: macaulay2.clear('R') # optional - macaulay2 - sage: macaulay2.eval('net class R') # optional - macaulay2 + sage: macaulay2.clear('R') + sage: macaulay2.eval('net class R') Symbol TESTS: @@ -484,11 +491,12 @@ def _contains(self, v1, v2): """ EXAMPLES:: - sage: a = macaulay2([3,4,5]) # optional - macaulay2 - sage: 0 in a, 2 in a, 3 in a # optional - macaulay2, indirect doctest + sage: # optional - macaulay2 + sage: a = macaulay2([3,4,5]) + sage: 0 in a, 2 in a, 3 in a (True, True, False) - sage: b = macaulay2('hashTable {"x" => 1, "y" => 2}') # optional - macaulay2 - sage: 'x' in b, '"x"' in b # optional - macaulay2, indirect doctest + sage: b = macaulay2('hashTable {"x" => 1, "y" => 2}') + sage: 'x' in b, '"x"' in b # indirect doctest (False, True) """ return self.eval("%s#?%s" % (v2, v1)) == self._true_symbol() @@ -559,7 +567,7 @@ def _install_hints(self): have Macaulay2 installed, or because it is not configured correctly. - Macaulay2 is not included with Sage, but you can obtain it from - https://faculty.math.illinois.edu/Macaulay2/. No additional + https://macaulay2.com/. No additional optional Sage packages are required. - If you have Macaulay2 installed, then perhaps it is not configured @@ -633,10 +641,11 @@ def cputime(self, t=None): """ EXAMPLES:: - sage: R = macaulay2("QQ[x,y]") # optional - macaulay2 - sage: x,y = R.gens() # optional - macaulay2 - sage: a = (x+y+1)^20 # optional - macaulay2 - sage: macaulay2.cputime() # optional - macaulay2; random + sage: # optional - macaulay2 + sage: R = macaulay2("QQ[x,y]") + sage: x,y = R.gens() + sage: a = (x+y+1)^20 + sage: macaulay2.cputime() # random 0.48393700000000001 """ _t = float(self.cpuTime()._sage_()) @@ -659,7 +668,7 @@ def version(self): s = r.search(s).groups()[0] return tuple(int(i) for i in s.split(".")) -### Constructors + # Constructors def ideal(self, *gens): """ @@ -790,13 +799,14 @@ def _tab_completion(self): TESTS:: - sage: names = macaulay2._tab_completion() # optional - macaulay2 - sage: 'ring' in names # optional - macaulay2 + sage: # optional - macaulay2 + sage: names = macaulay2._tab_completion() + sage: 'ring' in names True - sage: macaulay2.eval("abcabc = 4") # optional - macaulay2 + sage: macaulay2.eval("abcabc = 4") 4 - sage: names = macaulay2._tab_completion() # optional - macaulay2 - sage: "abcabc" in names # optional - macaulay2 + sage: names = macaulay2._tab_completion() + sage: "abcabc" in names True """ # Get all the names from Macaulay2 except numbered outputs like @@ -818,12 +828,13 @@ def use(self, R): EXAMPLES:: - sage: R = macaulay2("QQ[x,y]") # optional - macaulay2 - sage: P = macaulay2("ZZ/7[symbol x, symbol y]") # optional - macaulay2 - sage: macaulay2("x").cls()._operator('===', P) # optional - macaulay2 + sage: # optional - macaulay2 + sage: R = macaulay2("QQ[x,y]") + sage: P = macaulay2("ZZ/7[symbol x, symbol y]") + sage: macaulay2("x").cls()._operator('===', P) true - sage: macaulay2.use(R) # optional - macaulay2 - sage: macaulay2("x").cls()._operator('===', R) # optional - macaulay2 + sage: macaulay2.use(R) + sage: macaulay2("x").cls()._operator('===', R) true """ R = self(R) @@ -889,8 +900,8 @@ def _latex_(self): sage: latex(m) # optional - macaulay2 \left(\begin{smallmatrix} 1&2\\ 3&4\\ \end{smallmatrix}\right) """ - s = self.tex().external_string().strip('"').strip('$').replace('\\\\','\\') - s = s.replace(r"\bgroup","").replace(r"\egroup","") + s = self.tex().external_string().strip('"').strip('$').replace('\\\\', '\\') + s = s.replace(r"\bgroup", "").replace(r"\egroup", "") return s def __iter__(self): @@ -908,14 +919,15 @@ def __str__(self): """ EXAMPLES:: - sage: R = macaulay2("QQ[x,y,z]/(x^3-y^3-z^3)") # optional - macaulay2 - sage: x = macaulay2('x') # optional - macaulay2 - sage: y = macaulay2('y') # optional - macaulay2 - sage: str(x+y) # optional - macaulay2 + sage: # optional - macaulay2 + sage: R = macaulay2("QQ[x,y,z]/(x^3-y^3-z^3)") + sage: x = macaulay2('x') + sage: y = macaulay2('y') + sage: str(x+y) x + y - sage: str(macaulay2("QQ[x,y,z]")) # optional - macaulay2 + sage: str(macaulay2("QQ[x,y,z]")) QQ[x...z] - sage: str(macaulay2("QQ[x,y,z]/(x+y+z)")) # optional - macaulay2 + sage: str(macaulay2("QQ[x,y,z]/(x+y+z)")) QQ[x...z] -------... x + y + z @@ -927,24 +939,26 @@ def _repr_(self): """ EXAMPLES:: - sage: repr(macaulay2('1..25')) # optional - macaulay2 + sage: # optional - macaulay2 + sage: repr(macaulay2('1..25')) (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, -------------------------------------------------------------------------------- 23, 24, 25) - sage: str(macaulay2('1..25')) # optional - macaulay2 + sage: str(macaulay2('1..25')) (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25) If ``AfterPrint`` is enabled, the ``repr`` contains type information, but the string representation does not:: - sage: macaulay2.options.after_print = True # optional - macaulay2 - sage: repr(macaulay2('1..25')) # optional - macaulay2 + sage: # optional - macaulay2 + sage: macaulay2.options.after_print = True + sage: repr(macaulay2('1..25')) (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, -------------------------------------------------------------------------------- 23, 24, 25) Sequence - sage: str(macaulay2('1..25')) # optional - macaulay2 + sage: str(macaulay2('1..25')) (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25) sage: macaulay2.options.after_print = False # optional - macaulay2 """ @@ -980,7 +994,7 @@ def external_string(self): return P.eval('%s' % self.name()) raise RuntimeError("Error evaluating Macaulay2 code.\nIN:%s\nOUT:%s" % (code, X)) - s = multiple_replace({'\r':'', '\n':' '}, X) + s = multiple_replace({'\r': '', '\n': ' '}, X) return s def name(self, new_name=None): @@ -997,13 +1011,14 @@ def name(self, new_name=None): EXAMPLES:: - sage: S = macaulay2(QQ['x,y']) # optional - macaulay2 - sage: S.name() # optional - macaulay2 + sage: # optional - macaulay2 + sage: S = macaulay2(QQ['x,y']) + sage: S.name() 'sage...' - sage: R = S.name("R") # optional - macaulay2 - sage: R.name() # optional - macaulay2 + sage: R = S.name("R") + sage: R.name() 'R' - sage: R.vars().cokernel().resolution() # optional - macaulay2 + sage: R.vars().cokernel().resolution() 1 2 1 R <-- R <-- R <-- 0 @@ -1085,11 +1100,12 @@ def __call__(self, x): """ EXAMPLES:: - sage: R = macaulay2("QQ[x, y]") # optional - macaulay2 - sage: x,y = R.gens() # optional - macaulay2 - sage: I = macaulay2.ideal(x*y, x+y) # optional - macaulay2 - sage: gb = macaulay2.gb # optional - macaulay2 - sage: gb(I) # optional - macaulay2 + sage: # optional - macaulay2 + sage: R = macaulay2("QQ[x, y]") + sage: x,y = R.gens() + sage: I = macaulay2.ideal(x*y, x+y) + sage: gb = macaulay2.gb + sage: gb(I) GroebnerBasis[status: done; S-pairs encountered up to degree 1] """ self._check_valid() @@ -1107,14 +1123,15 @@ def __floordiv__(self, x): Now make the M2 version of R, so we can coerce elements of R to M2:: - sage: _ = macaulay2(R) # optional - macaulay2 - sage: h = macaulay2((x^3 + 2*y^2*x)^7); h # optional - macaulay2 + sage: # optional - macaulay2 + sage: _ = macaulay2(R) + sage: h = macaulay2((x^3 + 2*y^2*x)^7); h 21 7 14 x + 2x y - sage: h1 = macaulay2(x^2 + 2*y*x) # optional - macaulay2 - sage: h2 = macaulay2(x^3 + 2*y*x) # optional - macaulay2 - sage: u = h // [h1,h2] # optional - macaulay2 - sage: h == u[0]*h1 + u[1]*h2 + (h % [h1,h2]) # optional - macaulay2 + sage: h1 = macaulay2(x^2 + 2*y*x) + sage: h2 = macaulay2(x^3 + 2*y*x) + sage: u = h // [h1,h2] + sage: h == u[0]*h1 + u[1]*h2 + (h % [h1,h2]) True """ if isinstance(x, (list, tuple)): @@ -1134,16 +1151,17 @@ def __mod__(self, x): Now make the M2 version of R, so we can coerce elements of R to M2:: - sage: _ = macaulay2(R) # optional - macaulay2 - sage: h = macaulay2((x^3 + 2*y^2*x)^7); h # optional - macaulay2 + sage: # optional - macaulay2 + sage: _ = macaulay2(R) + sage: h = macaulay2((x^3 + 2*y^2*x)^7); h 21 7 14 x + 2x y - sage: h1 = macaulay2(x^2 + 2*y*x) # optional - macaulay2 - sage: h2 = macaulay2(x^3 + 2*y*x) # optional - macaulay2 - sage: h % [h1,h2] # optional - macaulay2 + sage: h1 = macaulay2(x^2 + 2*y*x) + sage: h2 = macaulay2(x^3 + 2*y*x) + sage: h % [h1,h2] -3x*y - sage: u = h // [h1,h2] # optional - macaulay2 - sage: h == u[0]*h1 + u[1]*h2 + (h % [h1,h2]) # optional - macaulay2 + sage: u = h // [h1,h2] + sage: h == u[0]*h1 + u[1]*h2 + (h % [h1,h2]) True """ if isinstance(x, (list, tuple)): @@ -1159,23 +1177,25 @@ def __bool__(self): EXAMPLES:: - sage: a = macaulay2(0) # optional - macaulay2 - sage: a == 0 # optional - macaulay2 + sage: # optional - macaulay2 + sage: a = macaulay2(0) + sage: a == 0 True - sage: bool(a) # optional - macaulay2 + sage: bool(a) False TESTS: Check that :trac:`28705` is fixed:: - sage: t = macaulay2(True); t # optional - macaulay2 + sage: # optional - macaulay2 + sage: t = macaulay2(True); t true - sage: bool(t) # optional - macaulay2 + sage: bool(t) True - sage: bool(macaulay2('false')) # optional - macaulay2 + sage: bool(macaulay2('false')) False - sage: bool(macaulay2('"a"')) # optional - macaulay2 + sage: bool(macaulay2('"a"')) True """ P = self.parent() @@ -1191,29 +1211,31 @@ def sage_polystring(self): EXAMPLES:: - sage: R = macaulay2.ring('QQ','(x,y)') # optional - macaulay2 - sage: f = macaulay2('x^3 + 3*y^11 + 5') # optional - macaulay2 - sage: print(f) # optional - macaulay2 + sage: # optional - macaulay2 + sage: R = macaulay2.ring('QQ','(x,y)') + sage: f = macaulay2('x^3 + 3*y^11 + 5') + sage: print(f) 3 11 x + 3y + 5 - sage: f.sage_polystring() # optional - macaulay2 + sage: f.sage_polystring() 'x**3+3*y**11+5' """ - return self.external_string().replace('^','**') + return self.external_string().replace('^', '**') def structure_sheaf(self): """ EXAMPLES:: - sage: S = macaulay2('QQ[a..d]') # optional - macaulay2 - sage: R = S / macaulay2('a^3 + b^3 + c^3 + d^3') # optional - macaulay2 - sage: X = R.Proj().name('X') # optional - macaulay2 - sage: X.structure_sheaf() # optional - macaulay2 + sage: # optional - macaulay2 + sage: S = macaulay2('QQ[a..d]') + sage: R = S / macaulay2('a^3 + b^3 + c^3 + d^3') + sage: X = R.Proj().name('X') + sage: X.structure_sheaf() doctest:...: DeprecationWarning: The function `structure_sheaf` is deprecated. Use `self.sheaf()` instead. See https://github.com/sagemath/sage/issues/27848 for details. OO X - sage: X.sheaf() # optional - macaulay2 + sage: X.sheaf() OO X """ @@ -1228,12 +1250,13 @@ def substitute(self, *args, **kwds): EXAMPLES:: - sage: R = macaulay2("QQ[x]") # optional - macaulay2 - sage: P = macaulay2("ZZ/7[symbol x]") # optional - macaulay2 - sage: x, = R.gens() # optional - macaulay2 - sage: a = x^2 + 1 # optional - macaulay2 - sage: a = a.substitute(P) # optional - macaulay2 - sage: a.sage().parent() # optional - macaulay2 + sage: # optional - macaulay2 + sage: R = macaulay2("QQ[x]") + sage: P = macaulay2("ZZ/7[symbol x]") + sage: x, = R.gens() + sage: a = x^2 + 1 + sage: a = a.substitute(P) + sage: a.sage().parent() Univariate Polynomial Ring in x over Finite Field of size 7 """ @@ -1253,9 +1276,10 @@ def _tab_completion(self): TESTS:: - sage: a = macaulay2("QQ[x,y]") # optional - macaulay2 - sage: traits = a._tab_completion() # optional - macaulay2 - sage: "generators" in traits # optional - macaulay2 + sage: # optional - macaulay2 + sage: a = macaulay2("QQ[x,y]") + sage: traits = a._tab_completion() + sage: "generators" in traits True The implementation of this function does not set or change global @@ -1298,7 +1322,6 @@ def cls(self): sage: macaulay2(ZZ).cls() # optional - macaulay2 Ring - """ return self.parent()("class %s" % self.name()) @@ -1325,16 +1348,17 @@ def after_print_text(self): return self.parent().eval('(lookup({topLevelMode,AfterPrint},' + 'class {0}))({0})'.format(self._name)) - ########################## - #Aliases for M2 operators# - ########################## + ############################ + # Aliases for M2 operators # + ############################ def dot(self, x): """ EXAMPLES:: - sage: d = macaulay2.new("MutableHashTable") # optional - macaulay2 - sage: d["k"] = 4 # optional - macaulay2 - sage: d.dot("k") # optional - macaulay2 + sage: # optional - macaulay2 + sage: d = macaulay2.new("MutableHashTable") + sage: d["k"] = 4 + sage: d.dot("k") 4 """ parent = self.parent() @@ -1348,10 +1372,11 @@ def _operator(self, opstr, x): EXAMPLES:: - sage: a = macaulay2("3") # optional - macaulay2 - sage: a._operator("+", a) # optional - macaulay2 + sage: # optional - macaulay2 + sage: a = macaulay2("3") + sage: a._operator("+", a) 6 - sage: a._operator("*", a) # optional - macaulay2 + sage: a._operator("*", a) 9 """ parent = self.parent() @@ -1392,106 +1417,121 @@ def underscore(self, x): """ return self._operator("_", x) - #################### - #Conversion to Sage# - #################### + ###################### + # Conversion to Sage # + ###################### def _sage_(self): r""" EXAMPLES:: - sage: macaulay2(ZZ).sage() # optional - macaulay2, indirect doctest + sage: # optional - macaulay2 + sage: macaulay2(ZZ).sage() # indirect doctest Integer Ring - sage: macaulay2(QQ).sage() # optional - macaulay2 + sage: macaulay2(QQ).sage() Rational Field - sage: macaulay2(2).sage() # optional - macaulay2 + sage: # optional - macaulay2 + sage: macaulay2(2).sage() 2 - sage: macaulay2(1/2).sage() # optional - macaulay2 + sage: macaulay2(1/2).sage() 1/2 - sage: macaulay2(2/1).sage() # optional - macaulay2 + sage: macaulay2(2/1).sage() 2 - sage: _.parent() # optional - macaulay2 + sage: _.parent() Rational Field - sage: macaulay2([1,2,3]).sage() # optional - macaulay2 + sage: macaulay2([1,2,3]).sage() [1, 2, 3] + sage: # optional - macaulay2 sage: m = matrix([[1,2],[3,4]]) - sage: macaulay2(m).sage() # optional - macaulay2 + sage: macaulay2(m).sage() [1 2] [3 4] - sage: D = macaulay2('hashTable {4 => 1, 2 => 3}') # optional - macaulay2 - sage: D.pairs() # optional - macaulay2 + sage: # optional - macaulay2 + sage: D = macaulay2('hashTable {4 => 1, 2 => 3}') + sage: D.pairs() {(4, 1), (2, 3)} - sage: D.sage() == {4: 1, 2: 3} # optional - macaulay2 + sage: D.sage() == {4: 1, 2: 3} True - sage: macaulay2(QQ['x,y']).sage() # optional - macaulay2 + sage: # optional - macaulay2 + sage: macaulay2(QQ['x,y']).sage() Multivariate Polynomial Ring in x, y over Rational Field - sage: macaulay2(QQ['x']).sage() # optional - macaulay2 + sage: macaulay2(QQ['x']).sage() Univariate Polynomial Ring in x over Rational Field - sage: macaulay2(GF(7)['x,y']).sage() # optional - macaulay2 + sage: macaulay2(GF(7)['x,y']).sage() Multivariate Polynomial Ring in x, y over Finite Field of size 7 - sage: macaulay2(GF(7)).sage() # optional - macaulay2 + sage: # optional - macaulay2 + sage: macaulay2(GF(7)).sage() Finite Field of size 7 - sage: macaulay2(GF(49, 'a')).sage() # optional - macaulay2 + sage: macaulay2(GF(49, 'a')).sage() Finite Field in a of size 7^2 sage: R. = QQ[] sage: macaulay2(x^2+y^2+1).sage() # optional - macaulay2 x^2 + y^2 + 1 - sage: R = macaulay2("QQ[x,y]") # optional - macaulay2 - sage: I = macaulay2("ideal (x,y)") # optional - macaulay2 - sage: I.sage() # optional - macaulay2 + sage: # optional - macaulay2 + sage: R = macaulay2("QQ[x,y]") + sage: I = macaulay2("ideal (x,y)") + sage: I.sage() Ideal (x, y) of Multivariate Polynomial Ring in x, y over Rational Field - sage: macaulay2("x = symbol x") # optional - macaulay2 + sage: # optional - macaulay2 + sage: macaulay2("x = symbol x") x - sage: macaulay2("QQ[x_0..x_25]").sage() # optional - macaulay2 + sage: macaulay2("QQ[x_0..x_25]").sage() Multivariate Polynomial Ring in x_0, x_1,..., x_25 over Rational Field + sage: # optional - macaulay2 sage: S = ZZ['x,y'].quotient('x^2-y') - sage: macaulay2(S).sage() == S # optional - macaulay2 + sage: macaulay2(S).sage() == S True sage: S = GF(101)['x,y'].quotient('x^2-y') - sage: macaulay2(S).sage() == S # optional - macaulay2 + sage: macaulay2(S).sage() == S True + sage: # optional - macaulay2 sage: R = GF(13)['a,b']['c,d'] - sage: macaulay2(R).sage() == R # optional - macaulay2 + sage: macaulay2(R).sage() == R True - sage: macaulay2('a^2 + c').sage() == R('a^2 + c') # optional - macaulay2 + sage: macaulay2('a^2 + c').sage() == R('a^2 + c') True - sage: macaulay2.substitute('a', R).sage().parent() is R # optional - macaulay2 + sage: macaulay2.substitute('a', R).sage().parent() is R True - sage: R = macaulay2("QQ^2") # optional - macaulay2 - sage: R.sage() # optional - macaulay2 + sage: # optional - macaulay2 + sage: R = macaulay2("QQ^2") + sage: R.sage() Vector space of dimension 2 over Rational Field - sage: macaulay2("vector {4_QQ, 2}").sage() # optional - macaulay2 + sage: # optional - macaulay2 + sage: macaulay2("vector {4_QQ, 2}").sage() (4, 2) - sage: _.parent() # optional - macaulay2 + sage: _.parent() Vector space of dimension 2 over Rational Field - sage: m = macaulay2('"hello"') # optional - macaulay2 - sage: m.sage() # optional - macaulay2 + sage: # optional - macaulay2 + sage: m = macaulay2('"hello"') + sage: m.sage() 'hello' - sage: gg = macaulay2.needsPackage('"Graphs"') # optional - macaulay2 - sage: g = macaulay2.barbellGraph(3) # optional - macaulay2 - sage: g.sage() # optional - macaulay2 + sage: # optional - macaulay2 + sage: gg = macaulay2.needsPackage('"Graphs"') + sage: g = macaulay2.barbellGraph(3) + sage: g.sage() Graph on 6 vertices - sage: g.sage().edges(labels=False) # optional - macaulay2 + sage: g.sage().edges(labels=False) [(0, 1), (0, 2), (1, 2), (2, 3), (3, 4), (3, 5), (4, 5)] + sage: # optional - macaulay2 sage: d = 'digraph ({{1,2},{2,1},{3,1}}, EntryMode => "edges")' - sage: g = macaulay2(d) # optional - macaulay2 - sage: g.sage() # optional - macaulay2 + sage: g = macaulay2(d) + sage: g.sage() Digraph on 3 vertices - sage: g.sage().edges(labels=False) # optional - macaulay2 + sage: g.sage().edges(labels=False) [(1, 2), (2, 1), (3, 1)] Chain complexes and maps of chain complexes can be converted:: @@ -1519,11 +1559,12 @@ def _sage_(self): Quotient rings in Macaulay2 inherit variable names from the ambient ring, so we mimic this behaviour in Sage:: - sage: R = macaulay2("ZZ/7[x,y]") # optional - macaulay2 - sage: I = macaulay2("ideal (x^3 - y^2)") # optional - macaulay2 - sage: (R/I).gens() # optional - macaulay2 + sage: # optional - macaulay2 + sage: R = macaulay2("ZZ/7[x,y]") + sage: I = macaulay2("ideal (x^3 - y^2)") + sage: (R/I).gens() {x, y} - sage: (R/I).sage().gens() # optional - macaulay2 + sage: (R/I).sage().gens() (x, y) Elements of quotient rings:: @@ -1559,7 +1600,7 @@ def _sage_(self): gens = self.gens().entries().flatten()._sage_() return parent.ideal(*gens) elif cls_str == "QuotientRing": - #Handle the ZZ/n case + # Handle the ZZ/n case ambient = self.ambient() if ambient.external_string() == 'ZZ': from sage.rings.integer_ring import ZZ @@ -1567,8 +1608,8 @@ def _sage_(self): external_string = self.external_string() zz, n = external_string.split("/") - #Note that n must be prime since it is - #coming from Macaulay 2 + # Note that n must be prime since it is + # coming from Macaulay 2 return GF(ZZ(n)) else: ambient_ring = ambient._sage_() @@ -1578,16 +1619,16 @@ def _sage_(self): from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing from sage.rings.polynomial.term_order import inv_macaulay2_name_mapping - #Get the base ring + # Get the base ring base_ring = self.coefficientRing()._sage_() - #Get a string list of generators + # Get a string list of generators gens = str(self.gens().toString())[1:-1] # Check that we are dealing with default degrees, i.e. 1's. if self.options().sharp("Degrees").any("x -> x != {1}")._sage_(): raise ValueError("cannot convert Macaulay2 polynomial ring with non-default degrees to Sage") - #Handle the term order + # Handle the term order external_string = self.external_string() order = None if "MonomialOrder" not in external_string: @@ -1642,7 +1683,7 @@ def _sage_(self): a = self.min()._sage_() b = self.max()._sage_() matrices = {i: dd.underscore(i)._matrix_(ring) - for i in range(a, b+1)} + for i in range(a, b + 1)} return ChainComplex(matrices, degree=degree) elif cls_str == "ChainComplexMap": from sage.homology.chain_complex_morphism import ChainComplexMorphism @@ -1652,14 +1693,14 @@ def _sage_(self): b = source.max()._sage_() degree = self.degree()._sage_() matrices = {i: self.underscore(i)._matrix_(ring) - for i in range(a, b+1)} + for i in range(a, b + 1)} C = source._sage_() # in Sage, chain complex morphisms are degree-preserving, # so we shift the degrees of the target D = self.target()._operator(' ', '[%s]' % degree)._sage_() return ChainComplexMorphism(matrices, C, D) else: - #Handle the integers and rationals separately + # Handle the integers and rationals separately if cls_str == "ZZ": from sage.rings.integer_ring import ZZ return ZZ(repr_str) @@ -1694,7 +1735,7 @@ def _matrix_(self, R): INPUT: - - ``R`` - ring to coerce into + - ``R`` -- ring to coerce into OUTPUT: matrix @@ -1869,7 +1910,6 @@ def macaulay2_console(): Macaulay 2, version 1.1 with packages: Classic, Core, Elimination, IntegralClosure, LLLBases, Parsing, PrimaryDecomposition, SchurRings, TangentCone ... - """ from sage.repl.rich_output.display_manager import get_display_manager if not get_display_manager().is_in_terminal(): From fe5d8f246c38ec96bd7925cc8c11c49767621ee2 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 16 Oct 2023 21:58:09 -0700 Subject: [PATCH 209/216] CI docbuild: Do not rebuild sagelib from scratch --- .github/workflows/doc-build-pdf.yml | 11 ++++++----- .github/workflows/doc-build.yml | 4 ++-- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/.github/workflows/doc-build-pdf.yml b/.github/workflows/doc-build-pdf.yml index 0413954210b..2ac2d164d2e 100644 --- a/.github/workflows/doc-build-pdf.yml +++ b/.github/workflows/doc-build-pdf.yml @@ -110,7 +110,7 @@ jobs: ./bootstrap && make build working-directory: ./worktree-image env: - MAKE: make -j2 + MAKE: make -j2 --output-sync=recurse SAGE_NUM_THREADS: 2 - name: Build (fallback to non-incremental) @@ -118,19 +118,20 @@ jobs: if: always() && steps.worktree.outcome == 'success' && steps.incremental.outcome != 'success' run: | set -ex - make doc-clean doc-uninstall sagelib-clean && git clean -fx src/sage && ./config.status && make build + make sagelib-clean && git clean -fx src/sage && ./config.status && make build working-directory: ./worktree-image env: - MAKE: make -j2 + MAKE: make -j2 --output-sync=recurse SAGE_NUM_THREADS: 2 - name: Build docs (PDF) id: docbuild if: always() && (steps.incremental.outcome == 'success' || steps.build.outcome == 'success') - run: make build V=0 && make doc-pdf + run: | + make doc-clean doc-uninstall; make doc-pdf working-directory: ./worktree-image env: - MAKE: make -j2 + MAKE: make -j2 --output-sync=recurse SAGE_NUM_THREADS: 2 - name: Copy docs diff --git a/.github/workflows/doc-build.yml b/.github/workflows/doc-build.yml index 355e07ab78e..341b5aa4d62 100644 --- a/.github/workflows/doc-build.yml +++ b/.github/workflows/doc-build.yml @@ -109,7 +109,7 @@ jobs: if: always() && steps.worktree.outcome == 'success' && steps.incremental.outcome != 'success' run: | set -ex - make doc-clean doc-uninstall sagelib-clean && git clean -fx src/sage && ./config.status && make build + make sagelib-clean && git clean -fx src/sage && ./config.status && make build working-directory: ./worktree-image env: MAKE: make -j2 --output-sync=recurse @@ -124,7 +124,7 @@ jobs: set -ex export SAGE_USE_CDNS=yes mv /sage/local/share/doc/sage/html/en/.git /sage/.git-doc - make doc-clean doc-uninstall sagelib-clean && git clean -fx src/sage + make doc-clean doc-uninstall mkdir -p /sage/local/share/doc/sage/html/en/ && mv /sage/.git-doc /sage/local/share/doc/sage/html/en/.git ./config.status && make doc-html working-directory: ./worktree-image From ab712c7d45715c7921d09897a9a9c26a4a71d344 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Tue, 17 Oct 2023 10:19:13 +0200 Subject: [PATCH 210/216] more fixes for M2 interface --- src/sage/interfaces/macaulay2.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sage/interfaces/macaulay2.py b/src/sage/interfaces/macaulay2.py index 1fd27a72bb3..9b5633bcf6a 100644 --- a/src/sage/interfaces/macaulay2.py +++ b/src/sage/interfaces/macaulay2.py @@ -1673,7 +1673,7 @@ def _sage_(self): graph_cls = DiGraph adj_mat = self.adjacencyMatrix().sage() g = graph_cls(adj_mat, format='adjacency_matrix') - g.relabel(self.vertices(sort=True)) + g.relabel(self.vertices()) return g elif cls_str == "ChainComplex": from sage.homology.chain_complex import ChainComplex @@ -1884,8 +1884,8 @@ def is_Macaulay2Element(x): sage: from sage.interfaces.macaulay2 import is_Macaulay2Element sage: is_Macaulay2Element(2) # optional - macaulay2 - doctest:...: DeprecationWarning: the function is_Macaulay2Element is deprecated; use isinstance(x, sage.interfaces.abc.MacaulayElement) instead - See https://github.com/sagemath/sage/issues/34823 for details. + doctest:...: DeprecationWarning: the function is_Macaulay2Element is deprecated; use isinstance(x, sage.interfaces.abc.Macaulay2Element) instead + See https://github.com/sagemath/sage/issues/34804 for details. False sage: is_Macaulay2Element(macaulay2(2)) # optional - macaulay2 True From 9bf58b83ebf987b5728b4382f330a6cf48d121b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Tue, 17 Oct 2023 10:23:43 +0200 Subject: [PATCH 211/216] version fix for M2 --- src/sage/interfaces/macaulay2.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/sage/interfaces/macaulay2.py b/src/sage/interfaces/macaulay2.py index 9b5633bcf6a..4ed5ab46542 100644 --- a/src/sage/interfaces/macaulay2.py +++ b/src/sage/interfaces/macaulay2.py @@ -656,16 +656,14 @@ def cputime(self, t=None): def version(self): """ - Returns the version of Macaulay2. + Return the version of Macaulay2 as a tuple. EXAMPLES:: sage: macaulay2.version() # optional - macaulay2 - (1, 1... + (1, ...) """ - s = self.eval("version") - r = re.compile("VERSION => (.*?)\n") - s = r.search(s).groups()[0] + s = self.eval('version#"VERSION"') return tuple(int(i) for i in s.split(".")) # Constructors From fe9cc935f578df33b5c881d82f631626c71c19e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Tue, 17 Oct 2023 11:04:04 +0200 Subject: [PATCH 212/216] add ruff to developer tools --- src/doc/en/developer/tools.rst | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/doc/en/developer/tools.rst b/src/doc/en/developer/tools.rst index a79d682c0c9..44eb0c595a3 100644 --- a/src/doc/en/developer/tools.rst +++ b/src/doc/en/developer/tools.rst @@ -219,6 +219,17 @@ Cython-lint `Cython-lint `_ checks Cython source files for coding style. +.. _section-tools-ruff: + +Ruff +==== + +`Ruff `_ is a powerful and fast linter +for Python code, written in C. + +It comes with a large choice of possible checks, and has the capacity +to fix some of the warnings it emits. + .. _section-tools-relint: Relint From d9bdfad44b0ab74443018f13b9de702acf9c6b40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Tue, 17 Oct 2023 14:30:41 +0200 Subject: [PATCH 213/216] not C but Rust --- src/doc/en/developer/tools.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/en/developer/tools.rst b/src/doc/en/developer/tools.rst index 44eb0c595a3..20878a6175d 100644 --- a/src/doc/en/developer/tools.rst +++ b/src/doc/en/developer/tools.rst @@ -225,7 +225,7 @@ Ruff ==== `Ruff `_ is a powerful and fast linter -for Python code, written in C. +for Python code, written in Rust. It comes with a large choice of possible checks, and has the capacity to fix some of the warnings it emits. From ee993d166a8d3c94c6e929b1c4d4472dc224ed7d Mon Sep 17 00:00:00 2001 From: Michael Orlitzky Date: Tue, 17 Oct 2023 09:01:35 -0400 Subject: [PATCH 214/216] src/sage/misc/persist.pyx: two docstring improvements in unpickle_all() --- src/sage/misc/persist.pyx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sage/misc/persist.pyx b/src/sage/misc/persist.pyx index d224185f47b..80d4f9b23d5 100644 --- a/src/sage/misc/persist.pyx +++ b/src/sage/misc/persist.pyx @@ -1102,9 +1102,9 @@ def unpickle_all(target, debug=False, run_test_suite=False): ``.sobj`` files. The tar archive can be in any format that python's ``tarfile`` module understands; for example, ``.tar.gz`` or ``.tar.bz2``. - - ``debug`` -- a boolean (default: False) + - ``debug`` -- a boolean (default: ``False``) whether to report a stacktrace in case of failure - - ``run_test_suite`` -- a boolean (default: False) + - ``run_test_suite`` -- a boolean (default: ``False``) whether to run ``TestSuite(x).run()`` on the unpickled objects OUTPUT: @@ -1120,7 +1120,7 @@ def unpickle_all(target, debug=False, run_test_suite=False): You must only pass trusted data to this function, including tar archives. We use the "data" filter from PEP 706 if possible while extracting the archive, but even that is not a perfect - solution, and it is only available since python-3.11.4. + solution, and it is only available since Python 3.11.4. EXAMPLES:: From aca1f936b73dacc7e7b787de8bda9e3f42c25f35 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 17 Oct 2023 10:57:47 -0700 Subject: [PATCH 215/216] build/sage_bootstrap/expand_class.py: Restore Python 2 compatibility --- build/sage_bootstrap/expand_class.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/build/sage_bootstrap/expand_class.py b/build/sage_bootstrap/expand_class.py index fb2c88f6e97..c7fdb308bd3 100644 --- a/build/sage_bootstrap/expand_class.py +++ b/build/sage_bootstrap/expand_class.py @@ -21,10 +21,11 @@ class PackageClass(object): - def __init__(self, *package_names_or_classes, exclude=(), - include_dependencies=False, exclude_dependencies=False, - **filters): + def __init__(self, *package_names_or_classes, **filters): self.__names = set() + exclude = filters.pop('exclude', ()) + include_dependencies = filters.pop('include_dependencies', False) + exclude_dependencies = filters.pop('exclude_dependencies', False) filenames = filters.pop('has_files', []) no_filenames = filters.pop('no_files', []) excluded = [] From 07a2afd65fb4b0a1c9cbc43ede7d4a18c921a000 Mon Sep 17 00:00:00 2001 From: Release Manager Date: Sat, 21 Oct 2023 17:07:11 +0200 Subject: [PATCH 216/216] Updated SageMath version to 10.2.beta8 --- .upstream.d/20-github.com-sagemath-sage-releases | 1 + CITATION.cff | 4 ++-- VERSION.txt | 2 +- build/pkgs/configure/checksums.ini | 6 +++--- build/pkgs/configure/package-version.txt | 2 +- build/pkgs/sage_conf/install-requires.txt | 2 +- build/pkgs/sage_docbuild/install-requires.txt | 2 +- build/pkgs/sage_setup/install-requires.txt | 2 +- build/pkgs/sage_sws2rst/install-requires.txt | 2 +- build/pkgs/sagelib/install-requires.txt | 2 +- build/pkgs/sagemath_bliss/install-requires.txt | 2 +- build/pkgs/sagemath_categories/install-requires.txt | 2 +- build/pkgs/sagemath_coxeter3/install-requires.txt | 2 +- build/pkgs/sagemath_environment/install-requires.txt | 2 +- build/pkgs/sagemath_mcqd/install-requires.txt | 2 +- build/pkgs/sagemath_meataxe/install-requires.txt | 2 +- build/pkgs/sagemath_objects/install-requires.txt | 2 +- build/pkgs/sagemath_repl/install-requires.txt | 2 +- build/pkgs/sagemath_sirocco/install-requires.txt | 2 +- build/pkgs/sagemath_tdlib/install-requires.txt | 2 +- pkgs/sage-conf/VERSION.txt | 2 +- pkgs/sage-conf_conda/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-bliss/VERSION.txt | 2 +- pkgs/sagemath-categories/VERSION.txt | 2 +- pkgs/sagemath-coxeter3/VERSION.txt | 2 +- pkgs/sagemath-environment/VERSION.txt | 2 +- pkgs/sagemath-mcqd/VERSION.txt | 2 +- pkgs/sagemath-meataxe/VERSION.txt | 2 +- pkgs/sagemath-objects/VERSION.txt | 2 +- pkgs/sagemath-repl/VERSION.txt | 2 +- pkgs/sagemath-sirocco/VERSION.txt | 2 +- pkgs/sagemath-tdlib/VERSION.txt | 2 +- src/VERSION.txt | 2 +- src/bin/sage-version.sh | 6 +++--- src/sage/version.py | 6 +++--- 39 files changed, 46 insertions(+), 45 deletions(-) diff --git a/.upstream.d/20-github.com-sagemath-sage-releases b/.upstream.d/20-github.com-sagemath-sage-releases index 6bccdd7ff0a..0176fddf829 100644 --- a/.upstream.d/20-github.com-sagemath-sage-releases +++ b/.upstream.d/20-github.com-sagemath-sage-releases @@ -1,3 +1,4 @@ # Upstream packages as uploaded as GitHub release assets. # This file is automatically updated by the sage-update-version script. +https://github.com/sagemath/sage/releases/download/10.2/ https://github.com/sagemath/sage/releases/download/10.1/ diff --git a/CITATION.cff b/CITATION.cff index c77984d3dbb..59a1b01420e 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -4,8 +4,8 @@ title: SageMath abstract: SageMath is a free open-source mathematics software system. authors: - name: "The SageMath Developers" -version: 10.2.beta7 +version: 10.2.beta8 doi: 10.5281/zenodo.593563 -date-released: 2023-10-14 +date-released: 2023-10-21 repository-code: "https://github.com/sagemath/sage" url: "https://www.sagemath.org/" diff --git a/VERSION.txt b/VERSION.txt index ec49d33b7ae..6c7fa387f09 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -1 +1 @@ -SageMath version 10.2.beta7, Release Date: 2023-10-14 +SageMath version 10.2.beta8, Release Date: 2023-10-21 diff --git a/build/pkgs/configure/checksums.ini b/build/pkgs/configure/checksums.ini index ca2edbcde73..99e471b97f6 100644 --- a/build/pkgs/configure/checksums.ini +++ b/build/pkgs/configure/checksums.ini @@ -1,4 +1,4 @@ tarball=configure-VERSION.tar.gz -sha1=bc6609d473876187585a7ebfe5324a2b9dd3dbf0 -md5=b4efc1d371167bb95352c5cc939a5d1b -cksum=63094869 +sha1=aa7054a0e6a582d2db1475dc47f63a54e6ac569f +md5=40eab024557ad51e08dfb08e2753a465 +cksum=802824779 diff --git a/build/pkgs/configure/package-version.txt b/build/pkgs/configure/package-version.txt index 449a917a992..f8291b5f3d7 100644 --- a/build/pkgs/configure/package-version.txt +++ b/build/pkgs/configure/package-version.txt @@ -1 +1 @@ -79d515e903a88ef416c6136c186bebdd461a8888 +c47788b02a42ef4907a0e61e702fbe9bbef27590 diff --git a/build/pkgs/sage_conf/install-requires.txt b/build/pkgs/sage_conf/install-requires.txt index 5fd72b717b4..af1494990e7 100644 --- a/build/pkgs/sage_conf/install-requires.txt +++ b/build/pkgs/sage_conf/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sage-conf ~= 10.2b7 +sage-conf ~= 10.2b8 diff --git a/build/pkgs/sage_docbuild/install-requires.txt b/build/pkgs/sage_docbuild/install-requires.txt index 4cae2a6bf49..3cd4fa3a1cc 100644 --- a/build/pkgs/sage_docbuild/install-requires.txt +++ b/build/pkgs/sage_docbuild/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sage-docbuild ~= 10.2b7 +sage-docbuild ~= 10.2b8 diff --git a/build/pkgs/sage_setup/install-requires.txt b/build/pkgs/sage_setup/install-requires.txt index 68cdb24f9e3..513270bef9b 100644 --- a/build/pkgs/sage_setup/install-requires.txt +++ b/build/pkgs/sage_setup/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sage-setup ~= 10.2b7 +sage-setup ~= 10.2b8 diff --git a/build/pkgs/sage_sws2rst/install-requires.txt b/build/pkgs/sage_sws2rst/install-requires.txt index 42e83833944..59a489617cb 100644 --- a/build/pkgs/sage_sws2rst/install-requires.txt +++ b/build/pkgs/sage_sws2rst/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sage-sws2rst ~= 10.2b7 +sage-sws2rst ~= 10.2b8 diff --git a/build/pkgs/sagelib/install-requires.txt b/build/pkgs/sagelib/install-requires.txt index 5c15582c630..254cd68ca8b 100644 --- a/build/pkgs/sagelib/install-requires.txt +++ b/build/pkgs/sagelib/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-standard ~= 10.2b7 +sagemath-standard ~= 10.2b8 diff --git a/build/pkgs/sagemath_bliss/install-requires.txt b/build/pkgs/sagemath_bliss/install-requires.txt index a3fac16d0c2..eb77a2780ee 100644 --- a/build/pkgs/sagemath_bliss/install-requires.txt +++ b/build/pkgs/sagemath_bliss/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-bliss ~= 10.2b7 +sagemath-bliss ~= 10.2b8 diff --git a/build/pkgs/sagemath_categories/install-requires.txt b/build/pkgs/sagemath_categories/install-requires.txt index 418ff006558..e087dd7435e 100644 --- a/build/pkgs/sagemath_categories/install-requires.txt +++ b/build/pkgs/sagemath_categories/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-categories ~= 10.2b7 +sagemath-categories ~= 10.2b8 diff --git a/build/pkgs/sagemath_coxeter3/install-requires.txt b/build/pkgs/sagemath_coxeter3/install-requires.txt index 80175254b35..5fbdb88a3e4 100644 --- a/build/pkgs/sagemath_coxeter3/install-requires.txt +++ b/build/pkgs/sagemath_coxeter3/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-coxeter3 ~= 10.2b7 +sagemath-coxeter3 ~= 10.2b8 diff --git a/build/pkgs/sagemath_environment/install-requires.txt b/build/pkgs/sagemath_environment/install-requires.txt index e5f989444fb..16b0a20b583 100644 --- a/build/pkgs/sagemath_environment/install-requires.txt +++ b/build/pkgs/sagemath_environment/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-environment ~= 10.2b7 +sagemath-environment ~= 10.2b8 diff --git a/build/pkgs/sagemath_mcqd/install-requires.txt b/build/pkgs/sagemath_mcqd/install-requires.txt index bf72ffd0cd0..cc5aee92b75 100644 --- a/build/pkgs/sagemath_mcqd/install-requires.txt +++ b/build/pkgs/sagemath_mcqd/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-mcqd ~= 10.2b7 +sagemath-mcqd ~= 10.2b8 diff --git a/build/pkgs/sagemath_meataxe/install-requires.txt b/build/pkgs/sagemath_meataxe/install-requires.txt index 2f0417b00e2..952fc3c6fa8 100644 --- a/build/pkgs/sagemath_meataxe/install-requires.txt +++ b/build/pkgs/sagemath_meataxe/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-meataxe ~= 10.2b7 +sagemath-meataxe ~= 10.2b8 diff --git a/build/pkgs/sagemath_objects/install-requires.txt b/build/pkgs/sagemath_objects/install-requires.txt index c2012d49e4f..1c578b75a97 100644 --- a/build/pkgs/sagemath_objects/install-requires.txt +++ b/build/pkgs/sagemath_objects/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-objects ~= 10.2b7 +sagemath-objects ~= 10.2b8 diff --git a/build/pkgs/sagemath_repl/install-requires.txt b/build/pkgs/sagemath_repl/install-requires.txt index dea07d5aadc..b2037903a68 100644 --- a/build/pkgs/sagemath_repl/install-requires.txt +++ b/build/pkgs/sagemath_repl/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-repl ~= 10.2b7 +sagemath-repl ~= 10.2b8 diff --git a/build/pkgs/sagemath_sirocco/install-requires.txt b/build/pkgs/sagemath_sirocco/install-requires.txt index 28d12c2352d..c62e361e6aa 100644 --- a/build/pkgs/sagemath_sirocco/install-requires.txt +++ b/build/pkgs/sagemath_sirocco/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-sirocco ~= 10.2b7 +sagemath-sirocco ~= 10.2b8 diff --git a/build/pkgs/sagemath_tdlib/install-requires.txt b/build/pkgs/sagemath_tdlib/install-requires.txt index a41568f6dfa..745ea5ccfe1 100644 --- a/build/pkgs/sagemath_tdlib/install-requires.txt +++ b/build/pkgs/sagemath_tdlib/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-tdlib ~= 10.2b7 +sagemath-tdlib ~= 10.2b8 diff --git a/pkgs/sage-conf/VERSION.txt b/pkgs/sage-conf/VERSION.txt index e3fab2e6628..66f8b2a93e1 100644 --- a/pkgs/sage-conf/VERSION.txt +++ b/pkgs/sage-conf/VERSION.txt @@ -1 +1 @@ -10.2.beta7 +10.2.beta8 diff --git a/pkgs/sage-conf_conda/VERSION.txt b/pkgs/sage-conf_conda/VERSION.txt index e3fab2e6628..66f8b2a93e1 100644 --- a/pkgs/sage-conf_conda/VERSION.txt +++ b/pkgs/sage-conf_conda/VERSION.txt @@ -1 +1 @@ -10.2.beta7 +10.2.beta8 diff --git a/pkgs/sage-conf_pypi/VERSION.txt b/pkgs/sage-conf_pypi/VERSION.txt index e3fab2e6628..66f8b2a93e1 100644 --- a/pkgs/sage-conf_pypi/VERSION.txt +++ b/pkgs/sage-conf_pypi/VERSION.txt @@ -1 +1 @@ -10.2.beta7 +10.2.beta8 diff --git a/pkgs/sage-docbuild/VERSION.txt b/pkgs/sage-docbuild/VERSION.txt index e3fab2e6628..66f8b2a93e1 100644 --- a/pkgs/sage-docbuild/VERSION.txt +++ b/pkgs/sage-docbuild/VERSION.txt @@ -1 +1 @@ -10.2.beta7 +10.2.beta8 diff --git a/pkgs/sage-setup/VERSION.txt b/pkgs/sage-setup/VERSION.txt index e3fab2e6628..66f8b2a93e1 100644 --- a/pkgs/sage-setup/VERSION.txt +++ b/pkgs/sage-setup/VERSION.txt @@ -1 +1 @@ -10.2.beta7 +10.2.beta8 diff --git a/pkgs/sage-sws2rst/VERSION.txt b/pkgs/sage-sws2rst/VERSION.txt index e3fab2e6628..66f8b2a93e1 100644 --- a/pkgs/sage-sws2rst/VERSION.txt +++ b/pkgs/sage-sws2rst/VERSION.txt @@ -1 +1 @@ -10.2.beta7 +10.2.beta8 diff --git a/pkgs/sagemath-bliss/VERSION.txt b/pkgs/sagemath-bliss/VERSION.txt index e3fab2e6628..66f8b2a93e1 100644 --- a/pkgs/sagemath-bliss/VERSION.txt +++ b/pkgs/sagemath-bliss/VERSION.txt @@ -1 +1 @@ -10.2.beta7 +10.2.beta8 diff --git a/pkgs/sagemath-categories/VERSION.txt b/pkgs/sagemath-categories/VERSION.txt index e3fab2e6628..66f8b2a93e1 100644 --- a/pkgs/sagemath-categories/VERSION.txt +++ b/pkgs/sagemath-categories/VERSION.txt @@ -1 +1 @@ -10.2.beta7 +10.2.beta8 diff --git a/pkgs/sagemath-coxeter3/VERSION.txt b/pkgs/sagemath-coxeter3/VERSION.txt index e3fab2e6628..66f8b2a93e1 100644 --- a/pkgs/sagemath-coxeter3/VERSION.txt +++ b/pkgs/sagemath-coxeter3/VERSION.txt @@ -1 +1 @@ -10.2.beta7 +10.2.beta8 diff --git a/pkgs/sagemath-environment/VERSION.txt b/pkgs/sagemath-environment/VERSION.txt index e3fab2e6628..66f8b2a93e1 100644 --- a/pkgs/sagemath-environment/VERSION.txt +++ b/pkgs/sagemath-environment/VERSION.txt @@ -1 +1 @@ -10.2.beta7 +10.2.beta8 diff --git a/pkgs/sagemath-mcqd/VERSION.txt b/pkgs/sagemath-mcqd/VERSION.txt index e3fab2e6628..66f8b2a93e1 100644 --- a/pkgs/sagemath-mcqd/VERSION.txt +++ b/pkgs/sagemath-mcqd/VERSION.txt @@ -1 +1 @@ -10.2.beta7 +10.2.beta8 diff --git a/pkgs/sagemath-meataxe/VERSION.txt b/pkgs/sagemath-meataxe/VERSION.txt index e3fab2e6628..66f8b2a93e1 100644 --- a/pkgs/sagemath-meataxe/VERSION.txt +++ b/pkgs/sagemath-meataxe/VERSION.txt @@ -1 +1 @@ -10.2.beta7 +10.2.beta8 diff --git a/pkgs/sagemath-objects/VERSION.txt b/pkgs/sagemath-objects/VERSION.txt index e3fab2e6628..66f8b2a93e1 100644 --- a/pkgs/sagemath-objects/VERSION.txt +++ b/pkgs/sagemath-objects/VERSION.txt @@ -1 +1 @@ -10.2.beta7 +10.2.beta8 diff --git a/pkgs/sagemath-repl/VERSION.txt b/pkgs/sagemath-repl/VERSION.txt index e3fab2e6628..66f8b2a93e1 100644 --- a/pkgs/sagemath-repl/VERSION.txt +++ b/pkgs/sagemath-repl/VERSION.txt @@ -1 +1 @@ -10.2.beta7 +10.2.beta8 diff --git a/pkgs/sagemath-sirocco/VERSION.txt b/pkgs/sagemath-sirocco/VERSION.txt index e3fab2e6628..66f8b2a93e1 100644 --- a/pkgs/sagemath-sirocco/VERSION.txt +++ b/pkgs/sagemath-sirocco/VERSION.txt @@ -1 +1 @@ -10.2.beta7 +10.2.beta8 diff --git a/pkgs/sagemath-tdlib/VERSION.txt b/pkgs/sagemath-tdlib/VERSION.txt index e3fab2e6628..66f8b2a93e1 100644 --- a/pkgs/sagemath-tdlib/VERSION.txt +++ b/pkgs/sagemath-tdlib/VERSION.txt @@ -1 +1 @@ -10.2.beta7 +10.2.beta8 diff --git a/src/VERSION.txt b/src/VERSION.txt index e3fab2e6628..66f8b2a93e1 100644 --- a/src/VERSION.txt +++ b/src/VERSION.txt @@ -1 +1 @@ -10.2.beta7 +10.2.beta8 diff --git a/src/bin/sage-version.sh b/src/bin/sage-version.sh index d4d11cb418d..e627d6e96d2 100644 --- a/src/bin/sage-version.sh +++ b/src/bin/sage-version.sh @@ -4,6 +4,6 @@ # which stops "setup.py develop" from rewriting it as a Python file. : # This file is auto-generated by the sage-update-version script, do not edit! -SAGE_VERSION='10.2.beta7' -SAGE_RELEASE_DATE='2023-10-14' -SAGE_VERSION_BANNER='SageMath version 10.2.beta7, Release Date: 2023-10-14' +SAGE_VERSION='10.2.beta8' +SAGE_RELEASE_DATE='2023-10-21' +SAGE_VERSION_BANNER='SageMath version 10.2.beta8, Release Date: 2023-10-21' diff --git a/src/sage/version.py b/src/sage/version.py index fac8596b5fa..ab26727486a 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 = '10.2.beta7' -date = '2023-10-14' -banner = 'SageMath version 10.2.beta7, Release Date: 2023-10-14' +version = '10.2.beta8' +date = '2023-10-21' +banner = 'SageMath version 10.2.beta8, Release Date: 2023-10-21'