diff --git a/.github/workflows/ci-linux-incremental.yml b/.github/workflows/ci-linux-incremental.yml index a7900534b32..47269bec46f 100644 --- a/.github/workflows/ci-linux-incremental.yml +++ b/.github/workflows/ci-linux-incremental.yml @@ -60,9 +60,9 @@ jobs: uninstall_targets=$(echo $(for a in '' ${{ steps.changed-files.outputs.configures_all_changed_files }}; do echo $a | sed -E 's,build/pkgs/([a-z0-9][_.a-z0-9]*)/spkg-configure[.]m4 *,\1-uninstall,'; done | sort -u)) build_targets=$(echo $(for a in '' ${{ steps.changed-files.outputs.pkgs_all_changed_files }}; do SPKG=$(echo $a | sed -E 's,-,_,g;s,(build/)?pkgs/([a-z0-9][-_.a-z0-9]*)/[^ ]* *,\2,;'); if [ -f "build/pkgs/$SPKG/checksums.ini" -o -f "build/pkgs/$SPKG/requirements.txt" -o -f "build/pkgs/$SPKG/spkg-install" ]; then echo "$SPKG-ensure"; fi; done | sort -u)) if [ -n "$uninstall_targets" ]; then - echo "build_targets=$uninstall_targets reconfigure $build_targets ci-build-with-fallback" >> $GITHUB_OUTPUT + echo "build_targets=$uninstall_targets reconfigure $build_targets" >> $GITHUB_OUTPUT else - echo "build_targets=$build_targets ci-build-with-fallback" >> $GITHUB_OUTPUT + echo "build_targets=$build_targets" >> $GITHUB_OUTPUT fi cat $GITHUB_OUTPUT - uses: actions/checkout@v4 @@ -92,7 +92,7 @@ jobs: from_docker_target: "with-targets" from_docker_tag: "dev" docker_targets: "with-targets" - targets: "${{needs.changed_files.outputs.build_targets}} doc-html ptest-nodoc" + targets: "${{needs.changed_files.outputs.build_targets}} ci-build-with-fallback doc-html ptest-nodoc" tox_system_factors: >- ["ubuntu-focal", "ubuntu-noble", @@ -108,6 +108,29 @@ jobs: docker_push_repository: ghcr.io/${{ github.repository }}/ max_parallel: 8 + constraints_pkgs-norequirements: + needs: [changed_files] + uses: ./.github/workflows/docker.yml + with: + # Build incrementally from published Docker image + incremental: true + free_disk_space: true + from_docker_repository: ghcr.io/sagemath/sage/ + from_docker_target: "with-targets-pre" + from_docker_tag: "dev" + docker_targets: "with-targets-pre" + targets_pre: "${{needs.changed_files.outputs.build_targets}} all-sage-local python3-ensure tox-ensure sagelib-tox-sagepython-constraints_pkgs-norequirements" + tox_system_factors: >- + ["ubuntu-focal", + "ubuntu-noble", + "debian-bookworm", + "fedora-40", + "debian-bullseye-i386"] + tox_packages_factors: >- + ["standard"] + docker_push_repository: ghcr.io/${{ github.repository }}/ + max_parallel: 16 + site: needs: [changed_files] uses: ./.github/workflows/docker.yml diff --git a/.github/workflows/ci-linux.yml b/.github/workflows/ci-linux.yml index cae29a27819..30cbe9b84cc 100644 --- a/.github/workflows/ci-linux.yml +++ b/.github/workflows/ci-linux.yml @@ -90,6 +90,22 @@ jobs: # and 'minimal-pre' below max_parallel: 20 + standard-constraints_pkgs-norequirements: + if: ${{ success() || failure() }} + needs: [standard-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-pre" + targets_pre: all-sage-local python3-ensure tox-ensure sagelib-tox-sagepython-constraints_pkgs-norequirements + tox_packages_factors: >- + ["standard"] + max_parallel: 15 + standard-sitepackages: if: ${{ success() || failure() }} needs: [standard-pre] diff --git a/build/make/Makefile.in b/build/make/Makefile.in index a59c81db529..420dadb9364 100644 --- a/build/make/Makefile.in +++ b/build/make/Makefile.in @@ -779,12 +779,14 @@ $(1)-sdist: FORCE python_build sage_setup cython . '$$(SAGE_ROOT)/src/bin/sage-env' && \ '$$(SAGE_ROOT)/build/pkgs/$(1)/spkg-src' -# Recursive tox invocation (note - we do not set the environment here). +# Recursive tox invocation # Setting SAGE_SPKG_WHEELS is for the benefit of sagelib's tox.ini $(1)-tox-%: FORCE $(AM_V_at)cd '$$(SAGE_ROOT)/build/pkgs/$(1)/src' && \ - export PATH="$$(SAGE_ORIG_PATH)" && \ - SAGE_SPKG_WHEELS=$$(SAGE_LOCAL)/var/lib/sage/wheels \ + . '$$(SAGE_ROOT)/src/bin/sage-src-env-config' && \ + . '$$(SAGE_ROOT)/src/bin/sage-env-config' && \ + . '$$(SAGE_ROOT)/src/bin/sage-env' && \ + SAGE_SPKG_WHEELS=$$(SAGE_VENV)/var/lib/sage/wheels \ tox -v -v -v -e $$* .PHONY: $(1) $(1)-uninstall $(1)-clean $(1)-build-deps $(1)-no-deps $(1)-clean diff --git a/constraints_pkgs.txt b/constraints_pkgs.txt new file mode 100644 index 00000000000..9e4fe969fbc --- /dev/null +++ b/constraints_pkgs.txt @@ -0,0 +1,39 @@ +# This "constraints file" can be used for forcing pip +# (and any tools that delegate to pip, such as pypa/build) +# to install the distribution packages included in +# the SageMath monorepository only from their source trees +# in SAGE_ROOT/pkgs/ instead of from PyPI. +# +# Example: Building a sagemath-standard wheel +# +# [alice@localhost sage]$ ./bootstrap +# [alice@localhost sage]$ ./configure +# [alice@localhost sage]$ export MAKE="make -j16" SAGE_NUM_THREADS=16 +# [alice@localhost sage]$ make all-sage-local +# [alice@localhost sage]$ export PIP_CONSTRAINT="$(pwd)/constraints_pkgs.txt" +# [alice@localhost sage]$ ./sage -sh -c 'python3 -m build -v -v pkgs/sagemath-standard' +# +# Non-example: Installing the built wheel using the same +# constraints file will fail because sagemath-standard is one +# of the distribution packages listed below. It will conflict +# with the built wheel for sagemath-standard! +# Use "pkgs/sagemath-standard/constraints_pkgs.txt" instead. + +# Reference on the format: +# https://pip.pypa.io/en/stable/user_guide/#constraints-files +# +sage_conf @ file://${SAGE_ROOT}/pkgs/sage-conf +sage_docbuild @ file://${SAGE_ROOT}/pkgs/sage-docbuild +sage_setup @ file://${SAGE_ROOT}/pkgs/sage-setup +sage_sws2rst @ file://${SAGE_ROOT}/pkgs/sage-sws2rst +sagemath-bliss @ file://${SAGE_ROOT}/pkgs/sagemath-bliss +sagemath-categories @ file://${SAGE_ROOT}/pkgs/sagemath-categories +sagemath-coxeter3 @ file://${SAGE_ROOT}/pkgs/sagemath-coxeter3 +sagemath-environment @ file://${SAGE_ROOT}/pkgs/sagemath-environment +sagemath-mcqd @ file://${SAGE_ROOT}/pkgs/sagemath-mcqd +sagemath-meataxe @ file://${SAGE_ROOT}/pkgs/sagemath-meataxe +sagemath-objects @ file://${SAGE_ROOT}/pkgs/sagemath-objects +sagemath-repl @ file://${SAGE_ROOT}/pkgs/sagemath-repl +sagemath-sirocco @ file://${SAGE_ROOT}/pkgs/sagemath-sirocco +sagemath-standard @ file://${SAGE_ROOT}/pkgs/sagemath-standard +sagemath-tdlib @ file://${SAGE_ROOT}/pkgs/sagemath-tdlib diff --git a/pkgs/sagemath-standard/README.rst b/pkgs/sagemath-standard/README.rst index f429984aa4c..b5d44eb1f9b 100644 --- a/pkgs/sagemath-standard/README.rst +++ b/pkgs/sagemath-standard/README.rst @@ -8,24 +8,26 @@ About SageMath "Creating a Viable Open Source Alternative to Magma, Maple, Mathematica, and MATLAB" - Copyright (C) 2005-2020 The Sage Development Team + Copyright (C) 2005-2024 The Sage Development Team https://www.sagemath.org SageMath fully supports all major Linux distributions, recent versions of macOS, and Windows (Windows Subsystem for Linux). -The traditional and recommended way to install SageMath is from source via Sage-the-distribution (https://www.sagemath.org/download-source.html). Sage-the-distribution first builds a large number of open source packages from source (unless it finds suitable versions installed in the system) and then installs the Sage Library (sagelib, implemented in Python and Cython). +See https://doc.sagemath.org/html/en/installation/index.html +for general installation instructions. -About this experimental pip-installable source distribution ------------------------------------------------------------ +About this pip-installable distribution package +----------------------------------------------- -This pip-installable source distribution `sagemath-standard` is an experimental distribution of the Sage Library. Use at your own risk. +This pip-installable source distribution `sagemath-standard` is a +distribution of the Sage Library. Building `sagemath-standard` has a large number of system packages as prerequisites. See https://doc.sagemath.org/html/en/installation/source.html#linux-recommended-installation for partial lists for various systems. -The connection to the system environment is facilitated through the https://pypi.org/project/sage-conf/ distribution package. +The connection to the system environment is facilitated through the https://pypi.org/project/sage-conf/ distribution package; for step-by-step installation instructions, see https://github.com/sagemath/sage/blob/develop/README.md#alternative-installation-using-pypi A modularization effort is in progress with the goal of making it possible to install parts of the Sage Library with fewer prerequisites. https://github.com/sagemath/sage/issues/29705 diff --git a/pkgs/sagemath-standard/constraints_pkgs.txt b/pkgs/sagemath-standard/constraints_pkgs.txt new file mode 100644 index 00000000000..139aae58f86 --- /dev/null +++ b/pkgs/sagemath-standard/constraints_pkgs.txt @@ -0,0 +1,21 @@ +# This "constraints file" can be used for forcing pip +# (and any tools that delegate to pip, such as pypa/build) +# to install the dependencies of sagemath-standard that are +# distribution packages included in the SageMath monorepository +# only from their source trees in SAGE_ROOT/pkgs/ +# instead of from PyPI. +# +# Example: +# +# [alice@localhost sage]$ ./bootstrap +# [alice@localhost sage]$ ./configure +# [alice@localhost sage]$ export MAKE="make -j16" SAGE_NUM_THREADS=16 +# [alice@localhost sage]$ make all-sage-local +# [alice@localhost sage]$ export PIP_CONSTRAINT="$(pwd)/pkgs/sagemath-standard/constraints_pkgs.txt" +# [alice@localhost sage]$ ./sage -sh -c 'python3 -m build -v -v pkgs/sagemath-standard' +# +# Reference on the format: +# https://pip.pypa.io/en/stable/user_guide/#constraints-files +# +sage_conf @ file://${SAGE_ROOT}/pkgs/sage-conf +sage_setup @ file://${SAGE_ROOT}/pkgs/sage-setup diff --git a/pkgs/sagemath-standard/tox.ini b/pkgs/sagemath-standard/tox.ini index c197f49d9be..0ac97f8a021 100644 --- a/pkgs/sagemath-standard/tox.ini +++ b/pkgs/sagemath-standard/tox.ini @@ -31,6 +31,19 @@ envlist = # # ./sage -sh -c '(cd pkgs/sagemath-standard && tox -v -v -v -e sagepython-sagewheels-nopypi)' # + # Build and test without using the concrete dependencies specified by requirements.txt, + # using the dependencies declared in pyproject.toml and setup.cfg (install-requires) only: + # Install the distribution packages included in the SageMath monorepository only from + # their source trees in SAGE_ROOT/pkgs/ (not from PyPI). + # + # ./sage -sh -c '(cd pkgs/sagemath-standard && tox -v -v -v -e sagepython-constraints_pkgs-norequirements)' + # + # Build dependencies according to requirements.txt (all versions fixed). + # Install the distribution packages included in the SageMath monorepository only from + # their source trees in SAGE_ROOT/pkgs/ (not from PyPI). + # + # ./sage -sh -c '(cd pkgs/sagemath-standard && tox -v -v -v -e sagepython-constraints_pkgs)' + # # EXPERIMENTAL ENVIRONMENTS: # # Build dependencies according to requirements.txt (all versions fixed). @@ -80,6 +93,8 @@ passenv = MAKEFLAGS # SAGE_VENV only for referring to the basepython or finding the wheels sagepython, sagewheels: SAGE_VENV + # Used as an environment variable in constraints_pkgs.txt + constraints_pkgs: SAGE_ROOT # Location of the wheels sagewheels: SAGE_SPKG_WHEELS @@ -88,6 +103,7 @@ setenv = # apply both to the installation of the dependencies and of the package sagewheels: PIP_FIND_LINKS=file://{env:SAGE_SPKG_WHEELS:{env:SAGE_VENV:{toxinidir}/../../../../venv}/var/lib/sage/wheels} nopypi: PIP_NO_INDEX=true + constraints_pkgs: PIP_CONSTRAINT={toxinidir}/constraints_pkgs.txt # No build isolation for PEP 517 packages - use what is already in the environment # Note that this pip env "NO" variable uses inverted logic: # PIP_NO_BUILD_ISOLATION=False means don't use build isolation. @@ -153,6 +169,17 @@ setenv = {[pkgenv]setenv} basepython = {env:SAGE_VENV}/bin/python3 +[testenv:.pkg-sagepython-constraints_pkgs] +passenv = {[pkgenv]passenv} + SAGE_VENV + # Location of constraints_pkgs.txt + SAGE_ROOT + +setenv = {[pkgenv]setenv} + PIP_CONSTRAINT={env:SAGE_ROOT}/constraints_pkgs.txt + +basepython = {env:SAGE_VENV}/bin/python3 + [testenv:sagepython] basepython = {env:SAGE_VENV}/bin/python3 package_env = .pkg-sagepython @@ -177,6 +204,14 @@ package_env = .pkg-sagepython basepython = {env:SAGE_VENV}/bin/python3 package_env = .pkg-sagepython +[testenv:sagepython-constraints_pkgs] +basepython = {env:SAGE_VENV}/bin/python3 +package_env = .pkg-sagepython-constraints_pkgs + +[testenv:sagepython-constraints_pkgs-norequirements] +basepython = {env:SAGE_VENV}/bin/python3 +package_env = .pkg-sagepython-constraints_pkgs + [testenv:sagepython-sagewheels-nopypi-norequirements] basepython = {env:SAGE_VENV}/bin/python3 diff --git a/src/pyproject.toml b/src/pyproject.toml index 4d2704f9469..7e3db40c898 100644 --- a/src/pyproject.toml +++ b/src/pyproject.toml @@ -14,6 +14,7 @@ requires = [ 'memory_allocator', 'numpy >=1.19', 'pkgconfig', + 'jinja2', ] build-backend = "setuptools.build_meta" diff --git a/src/sage/matroids/basis_exchange_matroid.pxd b/src/sage/matroids/basis_exchange_matroid.pxd index dc4b4aeb114..06c0c2cabb2 100644 --- a/src/sage/matroids/basis_exchange_matroid.pxd +++ b/src/sage/matroids/basis_exchange_matroid.pxd @@ -46,19 +46,19 @@ cdef class BasisExchangeMatroid(Matroid): cpdef _move_current_basis(self, X, Y) cpdef frozenset _max_independent(self, frozenset F) - cpdef int _rank(self, frozenset F) + cpdef int _rank(self, frozenset F) except -1 cpdef frozenset _circuit(self, frozenset F) cpdef frozenset _fundamental_circuit(self, frozenset B, e) cpdef frozenset _closure(self, frozenset F) cpdef frozenset _max_coindependent(self, frozenset F) - cpdef int _corank(self, frozenset F) + cpdef int _corank(self, frozenset F) noexcept cpdef frozenset _cocircuit(self, frozenset F) cpdef frozenset _fundamental_cocircuit(self, frozenset B, e) cpdef frozenset _coclosure(self, frozenset F) cpdef frozenset _augment(self, frozenset X, frozenset Y) - cpdef bint _is_independent(self, frozenset F) + cpdef bint _is_independent(self, frozenset F) noexcept cpdef list whitney_numbers2(self) cdef _whitney_numbers2_rec(self, object f_vec, bitset_t* flats, bitset_t* todo, long elt, long rnk) @@ -90,6 +90,6 @@ cdef class BasisExchangeMatroid(Matroid): cpdef _is_isomorphism(self, other, morphism) cdef bint __is_isomorphism(self, BasisExchangeMatroid other, morphism) noexcept - cpdef bint is_valid(self) + cpdef bint is_valid(self) noexcept cdef bint nxksrd(bitset_s *b, long n, long k, bint succ) noexcept diff --git a/src/sage/matroids/basis_exchange_matroid.pyx b/src/sage/matroids/basis_exchange_matroid.pyx index a3c4c897d16..422d9c71d90 100644 --- a/src/sage/matroids/basis_exchange_matroid.pyx +++ b/src/sage/matroids/basis_exchange_matroid.pyx @@ -652,7 +652,7 @@ cdef class BasisExchangeMatroid(Matroid): self.__max_independent(self._output, self._input) return self.__unpack(self._output) - cpdef int _rank(self, frozenset F): + cpdef int _rank(self, frozenset F) except -1: """ Compute the rank of a subset of the groundset. @@ -796,7 +796,7 @@ cdef class BasisExchangeMatroid(Matroid): self.__max_coindependent(self._output, self._input) return self.__unpack(self._output) - cpdef int _corank(self, frozenset F): + cpdef int _corank(self, frozenset F) noexcept: """ Return the corank of a set. @@ -940,7 +940,7 @@ cdef class BasisExchangeMatroid(Matroid): self.__augment(self._output, self._input, self._input2) return self.__unpack(self._output) - cpdef bint _is_independent(self, frozenset F): + cpdef bint _is_independent(self, frozenset F) noexcept: """ Test if input is independent. @@ -2231,7 +2231,7 @@ cdef class BasisExchangeMatroid(Matroid): return self._characteristic_setsystem()._isomorphism(other._characteristic_setsystem(), PS, PO) is not None - cpdef bint is_valid(self): + cpdef bint is_valid(self) noexcept: r""" Test if the data obey the matroid axioms. diff --git a/src/sage/matroids/basis_matroid.pxd b/src/sage/matroids/basis_matroid.pxd index 5789ad98937..fd240b01a38 100644 --- a/src/sage/matroids/basis_matroid.pxd +++ b/src/sage/matroids/basis_matroid.pxd @@ -15,7 +15,7 @@ cdef class BasisMatroid(BasisExchangeMatroid): cdef reset_current_basis(self) - cpdef bint _is_basis(self, frozenset X) + cpdef bint _is_basis(self, frozenset X) noexcept cpdef bases_count(self) cpdef SetSystem bases(self) diff --git a/src/sage/matroids/basis_matroid.pyx b/src/sage/matroids/basis_matroid.pyx index f9710eaac7c..b74a76af956 100644 --- a/src/sage/matroids/basis_matroid.pyx +++ b/src/sage/matroids/basis_matroid.pyx @@ -298,7 +298,7 @@ cdef class BasisMatroid(BasisExchangeMatroid): # a function that is very efficient for this class - cpdef bint _is_basis(self, frozenset X): + cpdef bint _is_basis(self, frozenset X) noexcept: """ Test if input is a basis. diff --git a/src/sage/matroids/circuit_closures_matroid.pxd b/src/sage/matroids/circuit_closures_matroid.pxd index 878443d86f3..2fe5629477c 100644 --- a/src/sage/matroids/circuit_closures_matroid.pxd +++ b/src/sage/matroids/circuit_closures_matroid.pxd @@ -5,9 +5,9 @@ cdef class CircuitClosuresMatroid(Matroid): cdef dict _circuit_closures # _CC cdef int _matroid_rank # _R cpdef frozenset groundset(self) - cpdef int _rank(self, frozenset X) + cpdef int _rank(self, frozenset X) except -1 cpdef full_rank(self) - cpdef bint _is_independent(self, frozenset F) + cpdef bint _is_independent(self, frozenset F) noexcept cpdef frozenset _max_independent(self, frozenset F) cpdef frozenset _circuit(self, frozenset F) cpdef dict circuit_closures(self) diff --git a/src/sage/matroids/circuit_closures_matroid.pyx b/src/sage/matroids/circuit_closures_matroid.pyx index 7dd29ee8143..d075792a2f4 100644 --- a/src/sage/matroids/circuit_closures_matroid.pyx +++ b/src/sage/matroids/circuit_closures_matroid.pyx @@ -179,7 +179,7 @@ cdef class CircuitClosuresMatroid(Matroid): """ return frozenset(self._groundset) - cpdef int _rank(self, frozenset X): + cpdef int _rank(self, frozenset X) except -1: """ Return the rank of a set ``X``. @@ -221,7 +221,7 @@ cdef class CircuitClosuresMatroid(Matroid): """ return self._matroid_rank - cpdef bint _is_independent(self, frozenset F): + cpdef bint _is_independent(self, frozenset F) noexcept: """ Test if input is independent. diff --git a/src/sage/matroids/circuits_matroid.pxd b/src/sage/matroids/circuits_matroid.pxd index f7b938a4d6f..7fa37c8cebe 100644 --- a/src/sage/matroids/circuits_matroid.pxd +++ b/src/sage/matroids/circuits_matroid.pxd @@ -9,9 +9,9 @@ cdef class CircuitsMatroid(Matroid): cdef list _sorted_C_lens cdef bint _nsc_defined cpdef frozenset groundset(self) - cpdef int _rank(self, frozenset X) + cpdef int _rank(self, frozenset X) except -1 cpdef full_rank(self) - cpdef bint _is_independent(self, frozenset X) + cpdef bint _is_independent(self, frozenset X) noexcept cpdef frozenset _max_independent(self, frozenset X) cpdef frozenset _circuit(self, frozenset X) cpdef frozenset _closure(self, frozenset X) @@ -27,11 +27,11 @@ cdef class CircuitsMatroid(Matroid): # properties cpdef girth(self) - cpdef bint is_paving(self) + cpdef bint is_paving(self) noexcept # isomorphism and relabeling cpdef _is_isomorphic(self, other, certificate=*) cpdef relabel(self, mapping) # verification - cpdef bint is_valid(self) + cpdef bint is_valid(self) noexcept diff --git a/src/sage/matroids/circuits_matroid.pyx b/src/sage/matroids/circuits_matroid.pyx index ae3be51d36f..fed8db3dd47 100644 --- a/src/sage/matroids/circuits_matroid.pyx +++ b/src/sage/matroids/circuits_matroid.pyx @@ -100,7 +100,7 @@ cdef class CircuitsMatroid(Matroid): """ return self._groundset - cpdef int _rank(self, frozenset X): + cpdef int _rank(self, frozenset X) except -1: """ Return the rank of a set ``X``. @@ -140,7 +140,7 @@ cdef class CircuitsMatroid(Matroid): """ return self._matroid_rank - cpdef bint _is_independent(self, frozenset X): + cpdef bint _is_independent(self, frozenset X) noexcept: """ Test if input is independent. @@ -850,7 +850,7 @@ cdef class CircuitsMatroid(Matroid): from sage.rings.infinity import infinity return min(self._k_C, default=infinity) - cpdef bint is_paving(self): + cpdef bint is_paving(self) noexcept: """ Return if ``self`` is paving. @@ -869,7 +869,7 @@ cdef class CircuitsMatroid(Matroid): # verification - cpdef bint is_valid(self): + cpdef bint is_valid(self) noexcept: r""" Test if ``self`` obeys the matroid axioms. diff --git a/src/sage/matroids/flats_matroid.pxd b/src/sage/matroids/flats_matroid.pxd index 956e30f859d..926cce035f2 100644 --- a/src/sage/matroids/flats_matroid.pxd +++ b/src/sage/matroids/flats_matroid.pxd @@ -8,9 +8,9 @@ cdef class FlatsMatroid(Matroid): cdef object _L # lattice of flats cpdef frozenset groundset(self) - cpdef int _rank(self, frozenset X) + cpdef int _rank(self, frozenset X) except -1 cpdef frozenset _closure(self, frozenset X) - cpdef bint _is_closed(self, frozenset X) + cpdef bint _is_closed(self, frozenset X) noexcept cpdef full_rank(self) @@ -24,4 +24,4 @@ cdef class FlatsMatroid(Matroid): cpdef relabel(self, mapping) # verification - cpdef bint is_valid(self) + cpdef bint is_valid(self) noexcept diff --git a/src/sage/matroids/flats_matroid.pyx b/src/sage/matroids/flats_matroid.pyx index 9c6a3c76aeb..369ae137b0a 100644 --- a/src/sage/matroids/flats_matroid.pyx +++ b/src/sage/matroids/flats_matroid.pyx @@ -114,7 +114,7 @@ cdef class FlatsMatroid(Matroid): """ return self._groundset - cpdef int _rank(self, frozenset X): + cpdef int _rank(self, frozenset X) except -1: """ Return the rank of a set ``X``. @@ -191,7 +191,7 @@ cdef class FlatsMatroid(Matroid): if f >= X: return f - cpdef bint _is_closed(self, frozenset X): + cpdef bint _is_closed(self, frozenset X) noexcept: """ Test if input is a closed set. @@ -539,7 +539,7 @@ cdef class FlatsMatroid(Matroid): # verification - cpdef bint is_valid(self): + cpdef bint is_valid(self) noexcept: r""" Test if ``self`` obeys the matroid axioms. diff --git a/src/sage/matroids/graphic_matroid.pxd b/src/sage/matroids/graphic_matroid.pxd index 8ec8dd9e8b0..32c243267ff 100644 --- a/src/sage/matroids/graphic_matroid.pxd +++ b/src/sage/matroids/graphic_matroid.pxd @@ -7,23 +7,23 @@ cdef class GraphicMatroid(Matroid): cdef dict _vertex_map cdef dict _groundset_edge_map cpdef frozenset groundset(self) - cpdef int _rank(self, frozenset X) + cpdef int _rank(self, frozenset X) except -1 cpdef _vertex_stars(self) cpdef _minor(self, contractions, deletions) cpdef _has_minor(self, N, bint certificate=*) - cpdef int _corank(self, frozenset X) - cpdef bint _is_circuit(self, frozenset X) + cpdef int _corank(self, frozenset X) noexcept + cpdef bint _is_circuit(self, frozenset X) noexcept cpdef frozenset _closure(self, frozenset X) cpdef frozenset _max_independent(self, frozenset X) cpdef frozenset _max_coindependent(self, frozenset X) cpdef frozenset _circuit(self, frozenset X) cpdef frozenset _coclosure(self, frozenset X) - cpdef bint _is_closed(self, frozenset X) + cpdef bint _is_closed(self, frozenset X) noexcept cpdef _is_isomorphic(self, other, certificate=*) cpdef _isomorphism(self, other) - cpdef bint is_valid(self) - cpdef bint is_graphic(self) - cpdef bint is_regular(self) + cpdef bint is_valid(self) noexcept + cpdef bint is_graphic(self) noexcept + cpdef bint is_regular(self) noexcept cpdef graph(self) cpdef vertex_map(self) cpdef list groundset_to_edges(self, X) diff --git a/src/sage/matroids/graphic_matroid.pyx b/src/sage/matroids/graphic_matroid.pyx index a01cef13fe3..b332897abeb 100644 --- a/src/sage/matroids/graphic_matroid.pyx +++ b/src/sage/matroids/graphic_matroid.pyx @@ -238,7 +238,7 @@ cdef class GraphicMatroid(Matroid): """ return self._groundset - cpdef int _rank(self, frozenset X): + cpdef int _rank(self, frozenset X) except -1: """ Return the rank of a set ``X``. @@ -625,7 +625,7 @@ cdef class GraphicMatroid(Matroid): N = N.regular_matroid() return M._has_minor(N, certificate=certificate) - cpdef int _corank(self, frozenset X): + cpdef int _corank(self, frozenset X) noexcept: """ Return the corank of the set `X` in the matroid. @@ -653,7 +653,7 @@ cdef class GraphicMatroid(Matroid): DS_vertices.union(u, v) return len(X) - (DS_vertices.number_of_subsets() - Integer(1)) - cpdef bint _is_circuit(self, frozenset X): + cpdef bint _is_circuit(self, frozenset X) noexcept: """ Test if input is a circuit. @@ -918,7 +918,7 @@ cdef class GraphicMatroid(Matroid): g.add_edge(e) return frozenset(XX) - cpdef bint _is_closed(self, frozenset X): + cpdef bint _is_closed(self, frozenset X) noexcept: """ Test if input is a closed set. @@ -1093,7 +1093,7 @@ cdef class GraphicMatroid(Matroid): """ return self.is_isomorphic(other, certificate=True)[1] - cpdef bint is_valid(self): + cpdef bint is_valid(self) noexcept: """ Test if the data obey the matroid axioms. @@ -1110,7 +1110,7 @@ cdef class GraphicMatroid(Matroid): """ return True - cpdef bint is_graphic(self): + cpdef bint is_graphic(self) noexcept: r""" Return if ``self`` is graphic. @@ -1124,7 +1124,7 @@ cdef class GraphicMatroid(Matroid): """ return True - cpdef bint is_regular(self): + cpdef bint is_regular(self) noexcept: r""" Return if ``self`` is regular. diff --git a/src/sage/matroids/linear_matroid.pxd b/src/sage/matroids/linear_matroid.pxd index 085a68be0f6..b0890a76148 100644 --- a/src/sage/matroids/linear_matroid.pxd +++ b/src/sage/matroids/linear_matroid.pxd @@ -62,7 +62,7 @@ cdef class LinearMatroid(BasisExchangeMatroid): cpdef _is_3connected_shifting(self, certificate=*) cpdef _is_4connected_shifting(self, certificate=*) - cpdef bint is_valid(self) + cpdef bint is_valid(self) noexcept cdef class BinaryMatroid(LinearMatroid): cdef tuple _b_invariant, _b_partition @@ -91,8 +91,8 @@ cdef class BinaryMatroid(LinearMatroid): cpdef _fast_isom_test(self, other) cpdef relabel(self, mapping) - cpdef bint is_graphic(self) - cpdef bint is_valid(self) + cpdef bint is_graphic(self) noexcept + cpdef bint is_valid(self) noexcept cdef class TernaryMatroid(LinearMatroid): @@ -122,7 +122,7 @@ cdef class TernaryMatroid(LinearMatroid): cpdef _fast_isom_test(self, other) cpdef relabel(self, mapping) - cpdef bint is_valid(self) + cpdef bint is_valid(self) noexcept cdef class QuaternaryMatroid(LinearMatroid): cdef object _x_zero, _x_one @@ -149,7 +149,7 @@ cdef class QuaternaryMatroid(LinearMatroid): cpdef _fast_isom_test(self, other) cpdef relabel(self, mapping) - cpdef bint is_valid(self) + cpdef bint is_valid(self) noexcept cdef class RegularMatroid(LinearMatroid): cdef _bases_count, _r_invariant @@ -172,6 +172,6 @@ cdef class RegularMatroid(LinearMatroid): cpdef has_line_minor(self, k, hyperlines=*, certificate=*) cpdef _linear_extension_chains(self, F, fundamentals=*) - cpdef bint is_regular(self) - cpdef bint is_graphic(self) - cpdef bint is_valid(self) + cpdef bint is_regular(self) noexcept + cpdef bint is_graphic(self) noexcept + cpdef bint is_valid(self) noexcept diff --git a/src/sage/matroids/linear_matroid.pyx b/src/sage/matroids/linear_matroid.pyx index 0310b8c2cd3..6848604f0c8 100644 --- a/src/sage/matroids/linear_matroid.pyx +++ b/src/sage/matroids/linear_matroid.pyx @@ -2614,7 +2614,7 @@ cdef class LinearMatroid(BasisExchangeMatroid): cochains = self.linear_coextension_cochains(F, cosimple=cosimple, fundamentals=fundamentals) return self._linear_coextensions(element, cochains) - cpdef bint is_valid(self): + cpdef bint is_valid(self) noexcept: r""" Test if the data represent an actual matroid. @@ -3793,7 +3793,7 @@ cdef class BinaryMatroid(LinearMatroid): keep_initial_representation=False) # graphicness test - cpdef bint is_graphic(self): + cpdef bint is_graphic(self) noexcept: """ Test if the binary matroid is graphic. @@ -3862,7 +3862,7 @@ cdef class BinaryMatroid(LinearMatroid): # now self is graphic iff there is a binary vector x so that M*x = 0 and x_0 = 1, so: return BinaryMatroid(m).corank(frozenset([0])) > 0 - cpdef bint is_valid(self): + cpdef bint is_valid(self) noexcept: r""" Test if the data obey the matroid axioms. @@ -4724,7 +4724,7 @@ cdef class TernaryMatroid(LinearMatroid): basis=bas, keep_initial_representation=False) - cpdef bint is_valid(self): + cpdef bint is_valid(self) noexcept: r""" Test if the data obey the matroid axioms. @@ -5488,7 +5488,7 @@ cdef class QuaternaryMatroid(LinearMatroid): basis=bas, keep_initial_representation=False) - cpdef bint is_valid(self): + cpdef bint is_valid(self) noexcept: r""" Test if the data obey the matroid axioms. @@ -6239,7 +6239,7 @@ cdef class RegularMatroid(LinearMatroid): fundamentals = set([1]) return LinearMatroid._linear_extension_chains(self, F, fundamentals) - cpdef bint is_graphic(self): + cpdef bint is_graphic(self) noexcept: """ Test if the regular matroid is graphic. @@ -6270,7 +6270,7 @@ cdef class RegularMatroid(LinearMatroid): """ return BinaryMatroid(reduced_matrix=self._reduced_representation()).is_graphic() - cpdef bint is_valid(self): + cpdef bint is_valid(self) noexcept: r""" Test if the data obey the matroid axioms. @@ -6299,7 +6299,7 @@ cdef class RegularMatroid(LinearMatroid): # representation - cpdef bint is_regular(self): + cpdef bint is_regular(self) noexcept: r""" Return if ``self`` is regular. diff --git a/src/sage/matroids/matroid.pxd b/src/sage/matroids/matroid.pxd index ca197f605b9..fd38cd0b249 100644 --- a/src/sage/matroids/matroid.pxd +++ b/src/sage/matroids/matroid.pxd @@ -9,28 +9,28 @@ cdef class Matroid(SageObject): # virtual methods cpdef frozenset groundset(self) - cpdef int _rank(self, frozenset X) + cpdef int _rank(self, frozenset X) except -1 # internal methods, assuming verified input cpdef frozenset _max_independent(self, frozenset X) cpdef frozenset _circuit(self, frozenset X) cpdef frozenset _fundamental_circuit(self, frozenset B, e) cpdef frozenset _closure(self, frozenset X) - cpdef int _corank(self, frozenset X) + cpdef int _corank(self, frozenset X) noexcept cpdef frozenset _max_coindependent(self, frozenset X) cpdef frozenset _cocircuit(self, frozenset X) cpdef frozenset _fundamental_cocircuit(self, frozenset B, e) cpdef frozenset _coclosure(self, frozenset X) cpdef frozenset _augment(self, frozenset X, frozenset Y) - cpdef bint _is_independent(self, frozenset X) - cpdef bint _is_basis(self, frozenset X) - cpdef bint _is_circuit(self, frozenset X) - cpdef bint _is_closed(self, frozenset X) - cpdef bint _is_coindependent(self, frozenset X) - cpdef bint _is_cobasis(self, frozenset X) - cpdef bint _is_cocircuit(self, frozenset X) - cpdef bint _is_coclosed(self, frozenset X) + cpdef bint _is_independent(self, frozenset X) noexcept + cpdef bint _is_basis(self, frozenset X) noexcept + cpdef bint _is_circuit(self, frozenset X) noexcept + cpdef bint _is_closed(self, frozenset X) noexcept + cpdef bint _is_coindependent(self, frozenset X) noexcept + cpdef bint _is_cobasis(self, frozenset X) noexcept + cpdef bint _is_cocircuit(self, frozenset X) noexcept + cpdef bint _is_coclosed(self, frozenset X) noexcept cpdef _minor(self, contractions, deletions) cpdef _has_minor(self, N, bint certificate=*) @@ -105,7 +105,7 @@ cdef class Matroid(SageObject): cpdef is_coclosed(self, X) # verification - cpdef bint is_valid(self) + cpdef bint is_valid(self) noexcept # enumeration cpdef SetSystem circuits(self, k=*) @@ -184,8 +184,8 @@ cdef class Matroid(SageObject): cpdef _is_3connected_CE(self, certificate=*) cpdef _is_3connected_BC(self, certificate=*) cpdef _is_3connected_BC_recursion(self, basis, fund_cocircuits) - cpdef bint is_paving(self) - cpdef bint is_sparse_paving(self) + cpdef bint is_paving(self) noexcept + cpdef bint is_sparse_paving(self) noexcept cpdef girth(self) # representability @@ -195,8 +195,8 @@ cdef class Matroid(SageObject): cpdef _local_ternary_matroid(self, basis=*) cpdef ternary_matroid(self, randomized_tests=*, verify=*) cpdef is_ternary(self, randomized_tests=*) - cpdef bint is_regular(self) - cpdef bint is_graphic(self) + cpdef bint is_regular(self) noexcept + cpdef bint is_graphic(self) noexcept # matroid k-closed cpdef is_k_closed(self, int k) diff --git a/src/sage/matroids/matroid.pyx b/src/sage/matroids/matroid.pyx index bfcf7d361a2..30ea73f1326 100644 --- a/src/sage/matroids/matroid.pyx +++ b/src/sage/matroids/matroid.pyx @@ -492,7 +492,7 @@ cdef class Matroid(SageObject): """ raise NotImplementedError("subclasses need to implement this") - cpdef int _rank(self, frozenset X): + cpdef int _rank(self, frozenset X) except -1: r""" Return the rank of a set ``X``. @@ -513,8 +513,9 @@ cdef class Matroid(SageObject): sage: M = sage.matroids.matroid.Matroid() sage: M._rank(frozenset([0, 1, 2])) - NotImplementedError: subclasses need to implement this + Traceback (most recent call last): ... + NotImplementedError: subclasses need to implement this """ raise NotImplementedError("subclasses need to implement this") @@ -732,7 +733,7 @@ cdef class Matroid(SageObject): XX.pop() return frozenset(XX) - cpdef int _corank(self, frozenset X): + cpdef int _corank(self, frozenset X) noexcept: """ Return the corank of a set. @@ -904,7 +905,7 @@ cdef class Matroid(SageObject): # override the following methods for even better efficiency - cpdef bint _is_independent(self, frozenset X): + cpdef bint _is_independent(self, frozenset X) noexcept: """ Test if input is independent. @@ -925,7 +926,7 @@ cdef class Matroid(SageObject): """ return len(X) == self._rank(X) - cpdef bint _is_basis(self, frozenset X): + cpdef bint _is_basis(self, frozenset X) noexcept: """ Test if input is a basis. @@ -958,7 +959,7 @@ cdef class Matroid(SageObject): """ return self._is_independent(X) - cpdef bint _is_circuit(self, frozenset X): + cpdef bint _is_circuit(self, frozenset X) noexcept: """ Test if input is a circuit. @@ -990,7 +991,7 @@ cdef class Matroid(SageObject): Z.add(x) return True - cpdef bint _is_closed(self, frozenset X): + cpdef bint _is_closed(self, frozenset X) noexcept: """ Test if input is a closed set. @@ -1019,7 +1020,7 @@ cdef class Matroid(SageObject): XX.discard(y) return True - cpdef bint _is_coindependent(self, frozenset X): + cpdef bint _is_coindependent(self, frozenset X) noexcept: """ Test if input is coindependent. @@ -1040,7 +1041,7 @@ cdef class Matroid(SageObject): """ return self._corank(X) == len(X) - cpdef bint _is_cobasis(self, frozenset X): + cpdef bint _is_cobasis(self, frozenset X) noexcept: """ Test if input is a cobasis. @@ -1068,7 +1069,7 @@ cdef class Matroid(SageObject): """ return self._is_basis(self.groundset().difference(X)) - cpdef bint _is_cocircuit(self, frozenset X): + cpdef bint _is_cocircuit(self, frozenset X) noexcept: """ Test if input is a cocircuit. @@ -1100,7 +1101,7 @@ cdef class Matroid(SageObject): Z.add(x) return True - cpdef bint _is_coclosed(self, frozenset X): + cpdef bint _is_coclosed(self, frozenset X) noexcept: """ Test if input is a coclosed set. @@ -2305,7 +2306,7 @@ cdef class Matroid(SageObject): # verification - cpdef bint is_valid(self): + cpdef bint is_valid(self) noexcept: r""" Test if the data obey the matroid axioms. @@ -2338,7 +2339,7 @@ cdef class Matroid(SageObject): TESTS:: sage: def r(X): - ....: return -1 + ....: return -2 sage: M = Matroid(groundset=[0,1,2], rank_function=r) sage: M.is_valid() False @@ -6187,7 +6188,7 @@ cdef class Matroid(SageObject): return False return True - cpdef bint is_paving(self): + cpdef bint is_paving(self) noexcept: """ Return if ``self`` is paving. @@ -6210,7 +6211,7 @@ cdef class Matroid(SageObject): return False return True - cpdef bint is_sparse_paving(self): + cpdef bint is_sparse_paving(self) noexcept: """ Return if ``self`` is sparse-paving. @@ -6577,7 +6578,7 @@ cdef class Matroid(SageObject): """ return self.ternary_matroid(randomized_tests=randomized_tests, verify=True) is not None - cpdef bint is_graphic(self): + cpdef bint is_graphic(self) noexcept: r""" Return if ``self`` is graphic. @@ -6611,7 +6612,7 @@ cdef class Matroid(SageObject): return False return True - cpdef bint is_regular(self): + cpdef bint is_regular(self) noexcept: r""" Return if ``self`` is regular. diff --git a/src/sage/matroids/union_matroid.pxd b/src/sage/matroids/union_matroid.pxd index 518ca54bba9..10d995e28c5 100644 --- a/src/sage/matroids/union_matroid.pxd +++ b/src/sage/matroids/union_matroid.pxd @@ -5,16 +5,16 @@ cdef class MatroidUnion(Matroid): cdef list matroids cdef frozenset _groundset cpdef frozenset groundset(self) - cpdef int _rank(self, frozenset X) + cpdef int _rank(self, frozenset X) except -1 cdef class MatroidSum(Matroid): cdef list summands cdef frozenset _groundset cpdef frozenset groundset(self) - cpdef int _rank(self, frozenset X) + cpdef int _rank(self, frozenset X) except -1 cdef class PartitionMatroid(Matroid): cdef dict p cdef frozenset _groundset cpdef frozenset groundset(self) - cpdef int _rank(self, frozenset X) + cpdef int _rank(self, frozenset X) except -1 diff --git a/src/sage/matroids/union_matroid.pyx b/src/sage/matroids/union_matroid.pyx index ef40d0fc1b2..54b57434565 100644 --- a/src/sage/matroids/union_matroid.pyx +++ b/src/sage/matroids/union_matroid.pyx @@ -66,7 +66,7 @@ cdef class MatroidUnion(Matroid): """ return self._groundset - cpdef int _rank(self, frozenset X): + cpdef int _rank(self, frozenset X) except -1: r""" Return the rank of a set ``X``. @@ -195,7 +195,7 @@ cdef class MatroidSum(Matroid): """ return self._groundset - cpdef int _rank(self, frozenset X): + cpdef int _rank(self, frozenset X) except -1: r""" Return the rank of a set ``X``. @@ -290,7 +290,7 @@ cdef class PartitionMatroid(Matroid): """ return self._groundset - cpdef int _rank(self, frozenset X): + cpdef int _rank(self, frozenset X) except -1: r""" Return the rank of a set ``X``. diff --git a/src/sage/sets/disjoint_set.pxd b/src/sage/sets/disjoint_set.pxd index 3c8351983e7..4d981718568 100644 --- a/src/sage/sets/disjoint_set.pxd +++ b/src/sage/sets/disjoint_set.pxd @@ -19,8 +19,8 @@ cdef class DisjointSet_class(SageObject): cpdef number_of_subsets(self) cdef class DisjointSet_of_integers(DisjointSet_class): - cpdef int find(self, int i) - cpdef void union(self, int i, int j) + cpdef int find(self, int i) except -1 + cpdef void union(self, int i, int j) except * cpdef root_to_elements_dict(self) cpdef element_to_root_dict(self) cpdef to_digraph(self) @@ -29,7 +29,7 @@ cdef class DisjointSet_of_hashables(DisjointSet_class): cdef list _int_to_el cdef dict _el_to_int cpdef find(self, e) - cpdef void union(self, e, f) + cpdef void union(self, e, f) noexcept cpdef root_to_elements_dict(self) cpdef element_to_root_dict(self) cpdef to_digraph(self) diff --git a/src/sage/sets/disjoint_set.pyx b/src/sage/sets/disjoint_set.pyx index 1c2d93fea2a..02cf77fbdd7 100644 --- a/src/sage/sets/disjoint_set.pyx +++ b/src/sage/sets/disjoint_set.pyx @@ -448,7 +448,7 @@ cdef class DisjointSet_of_integers(DisjointSet_class): for i, parent in enumerate(l): self.union(parent, i) - cpdef int find(self, int i): + cpdef int find(self, int i) except -1: r""" Return the representative of the set that ``i`` currently belongs to. @@ -479,8 +479,9 @@ cdef class DisjointSet_of_integers(DisjointSet_class): sage: [e.find(i) for i in range(5)] [0, 1, 1, 1, 1] sage: e.find(2**10) - ValueError: i must be between 0 and 4 (1024 given) + Traceback (most recent call last): ... + ValueError: i must be between 0 and 4 (1024 given) .. NOTE:: @@ -492,7 +493,7 @@ cdef class DisjointSet_of_integers(DisjointSet_class): raise ValueError('i must be between 0 and %s (%s given)' % (card - 1, i)) return OP_find(self._nodes, i) - cpdef void union(self, int i, int j): + cpdef void union(self, int i, int j) except *: r""" Combine the set of ``i`` and the set of ``j`` into one. @@ -520,8 +521,9 @@ cdef class DisjointSet_of_integers(DisjointSet_class): sage: d {{0, 1, 2, 4}, {3}} sage: d.union(1, 5) - ValueError: j must be between 0 and 4 (5 given) + Traceback (most recent call last): ... + ValueError: j must be between 0 and 4 (5 given) .. NOTE:: @@ -797,7 +799,7 @@ cdef class DisjointSet_of_hashables(DisjointSet_class): cdef int r = OP_find(self._nodes, i) return self._int_to_el[r] - cpdef void union(self, e, f): + cpdef void union(self, e, f) noexcept: r""" Combine the set of ``e`` and the set of ``f`` into one.