From 7766f50822aac6e5cc703f653fd53e9bd8d989d9 Mon Sep 17 00:00:00 2001 From: cxzhong Date: Sun, 17 Aug 2025 23:21:57 +0800 Subject: [PATCH 1/7] Enhance editable install process with incremental build support --- Makefile | 9 +++++++++ build/pkgs/sagelib/spkg-install.in | 13 ++++++++++--- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 4b5e9350d3e..b0c4cb2fa05 100644 --- a/Makefile +++ b/Makefile @@ -115,6 +115,15 @@ clean: # "c_lib", ".cython_version", "build" in $(SAGE_SRC) are from old sage versions # Cleaning .so files (and .c and .cpp files associated with .pyx files) is for editable installs. # Also cython_debug is for editable installs. +# +# NOTE: Editable installs with incremental compilation are now the default. +# - First build: Full editable install with pip install -e +# - Subsequent builds: Incremental compilation with setup.py build_ext --inplace +# +# For manual incremental compilation, use the Sage Python environment: +# cd src && ../sage --python setup.py build_ext --inplace +# This will only recompile changed Cython extensions in place. +# Or use: make sagelib (which will rebuild all of sagelib) sagelib-clean: @echo "Deleting Sage library build artifacts..." if [ -d "$(SAGE_SRC)" ]; then \ diff --git a/build/pkgs/sagelib/spkg-install.in b/build/pkgs/sagelib/spkg-install.in index 5c78e3459c8..f2fb3889f71 100644 --- a/build/pkgs/sagelib/spkg-install.in +++ b/build/pkgs/sagelib/spkg-install.in @@ -46,9 +46,16 @@ SITEPACKAGESDIR=$(python3 -c 'import sysconfig; print(sysconfig.get_paths()["pur # does not shadow the namespace package sage during the build. (cd "$SITEPACKAGESDIR" && rm -f sage/__init__.py) if [ "$SAGE_EDITABLE" = yes ]; then - # Until https://github.com/sagemath/sage/issues/34209 switches us to PEP 660 editable wheels - export SETUPTOOLS_ENABLE_FEATURES=legacy-editable - sdh_pip_editable_install . + # Check if this is an incremental build by looking for existing editable install + if python3 -c "import importlib.metadata; importlib.metadata.distribution('sagemath-standard')" 2>/dev/null && \ + python3 -c "import sage; import os; exit(0 if os.path.exists(os.path.join(os.path.dirname(sage.__file__), '..', 'setup.py')) else 1)" 2>/dev/null; then + echo "Detected existing editable install - performing incremental build" + # Use setup.py build_ext --inplace for incremental compilation + python3 setup.py build_ext --inplace || sdh_die "Error during incremental build" + else + echo "Performing initial editable install" + sdh_pip_editable_install . + fi if [ "$SAGE_WHEELS" = yes ]; then # Additionally build a wheel (for use in other venvs) From bb86f560c5aa1835353f00516ae9c6d25a404b43 Mon Sep 17 00:00:00 2001 From: cxzhong Date: Mon, 18 Aug 2025 00:09:11 +0800 Subject: [PATCH 2/7] Enhance incremental build support for editable installs for setutools>=79 --- build/pkgs/sagelib/spkg-install.in | 1 + 1 file changed, 1 insertion(+) diff --git a/build/pkgs/sagelib/spkg-install.in b/build/pkgs/sagelib/spkg-install.in index f2fb3889f71..987543b1fd5 100644 --- a/build/pkgs/sagelib/spkg-install.in +++ b/build/pkgs/sagelib/spkg-install.in @@ -52,6 +52,7 @@ if [ "$SAGE_EDITABLE" = yes ]; then echo "Detected existing editable install - performing incremental build" # Use setup.py build_ext --inplace for incremental compilation python3 setup.py build_ext --inplace || sdh_die "Error during incremental build" + sdh_pip_editable_install . || sdh_die "Error during incremental install" else echo "Performing initial editable install" sdh_pip_editable_install . From 2c5be37941914dcbea18deb106085e9b7c84310c Mon Sep 17 00:00:00 2001 From: cxzhong Date: Mon, 18 Aug 2025 00:24:36 +0800 Subject: [PATCH 3/7] Enhance incremental build process for editable installs in sagelib --- build/pkgs/sagelib/spkg-install.in | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/build/pkgs/sagelib/spkg-install.in b/build/pkgs/sagelib/spkg-install.in index 987543b1fd5..53bb039efae 100644 --- a/build/pkgs/sagelib/spkg-install.in +++ b/build/pkgs/sagelib/spkg-install.in @@ -52,7 +52,7 @@ if [ "$SAGE_EDITABLE" = yes ]; then echo "Detected existing editable install - performing incremental build" # Use setup.py build_ext --inplace for incremental compilation python3 setup.py build_ext --inplace || sdh_die "Error during incremental build" - sdh_pip_editable_install . || sdh_die "Error during incremental install" + # No need to reinstall - editable install is already in place else echo "Performing initial editable install" sdh_pip_editable_install . @@ -63,12 +63,25 @@ if [ "$SAGE_EDITABLE" = yes ]; then cd $SAGE_PKGS/sagelib/src && time sdh_build_and_store_wheel --no-build-isolation . fi else - # Now implied: "$SAGE_WHEELS" = yes - # We should remove the egg-link that may have been installed previously. - (cd "$SITEPACKAGESDIR" && rm -f sagemath-standard.egg-link) - # Use --no-build-isolation to avoid rebuilds because of dependencies: - # Compiling sage/interfaces/sagespawn.pyx because it depends on /private/var/folders/38/wnh4gf1552g_crsjnv2vmmww0000gp/T/pip-build-env-609n5985/overlay/lib/python3.10/site-packages/Cython/Includes/posix/unistd.pxd - sdh_pip_install --no-build-isolation . + # Check if this is an incremental build by looking for existing sagelib installation + if python3 -c "import importlib.metadata; importlib.metadata.distribution('sagemath-standard')" 2>/dev/null; then + echo "Detected existing sagelib installation - performing incremental build only" + # Use setup.py build_ext for incremental compilation only + python3 setup.py build_ext || sdh_die "Error during incremental build" + # For non-editable mode, we need to install to make changes available + python3 setup.py install || sdh_die "Error during incremental install" + elif [ "$SAGE_WHEELS" = yes ]; then + # Now implied: "$SAGE_WHEELS" = yes + # We should remove the egg-link that may have been installed previously. + (cd "$SITEPACKAGESDIR" && rm -f sagemath-standard.egg-link) + # Use --no-build-isolation to avoid rebuilds because of dependencies: + # Compiling sage/interfaces/sagespawn.pyx because it depends on /private/var/folders/38/wnh4gf1552g_crsjnv2vmmww0000gp/T/pip-build-env-609n5985/overlay/lib/python3.10/site-packages/Cython/Includes/posix/unistd.pxd + sdh_pip_install --no-build-isolation . + else + # Fallback: regular install for development + echo "Performing regular install" + python3 setup.py install || sdh_die "Error during install" + fi fi # Remove (potentially invalid) star import caches. From 0f4c64d183ec89742c2d8997a4cf3f434f52b47c Mon Sep 17 00:00:00 2001 From: cxzhong Date: Mon, 18 Aug 2025 00:44:46 +0800 Subject: [PATCH 4/7] fix rebuild problem --- build/pkgs/sagelib/spkg-install.in | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/build/pkgs/sagelib/spkg-install.in b/build/pkgs/sagelib/spkg-install.in index 53bb039efae..543bf47f0d7 100644 --- a/build/pkgs/sagelib/spkg-install.in +++ b/build/pkgs/sagelib/spkg-install.in @@ -46,15 +46,14 @@ SITEPACKAGESDIR=$(python3 -c 'import sysconfig; print(sysconfig.get_paths()["pur # does not shadow the namespace package sage during the build. (cd "$SITEPACKAGESDIR" && rm -f sage/__init__.py) if [ "$SAGE_EDITABLE" = yes ]; then - # Check if this is an incremental build by looking for existing editable install - if python3 -c "import importlib.metadata; importlib.metadata.distribution('sagemath-standard')" 2>/dev/null && \ - python3 -c "import sage; import os; exit(0 if os.path.exists(os.path.join(os.path.dirname(sage.__file__), '..', 'setup.py')) else 1)" 2>/dev/null; then - echo "Detected existing editable install - performing incremental build" + # Check if we already have an editable install + if ls "$SITEPACKAGESDIR"/__editable__*sagemath* 2>/dev/null || ls "$SITEPACKAGESDIR"/sagemath*.egg-link 2>/dev/null; then + echo "Detected existing editable install - performing incremental build only" # Use setup.py build_ext --inplace for incremental compilation python3 setup.py build_ext --inplace || sdh_die "Error during incremental build" - # No need to reinstall - editable install is already in place + # No reinstall needed - editable install is already in place else - echo "Performing initial editable install" + echo "No editable install found - performing initial editable install" sdh_pip_editable_install . fi From 94d9bae3a58c81056db08cb631591b1f05b3cd62 Mon Sep 17 00:00:00 2001 From: cxzhong Date: Mon, 18 Aug 2025 00:56:57 +0800 Subject: [PATCH 5/7] roll back unnecessary part --- build/pkgs/sagelib/spkg-install.in | 36 ++++++++++-------------------- 1 file changed, 12 insertions(+), 24 deletions(-) diff --git a/build/pkgs/sagelib/spkg-install.in b/build/pkgs/sagelib/spkg-install.in index 543bf47f0d7..0856e91db35 100644 --- a/build/pkgs/sagelib/spkg-install.in +++ b/build/pkgs/sagelib/spkg-install.in @@ -46,14 +46,15 @@ SITEPACKAGESDIR=$(python3 -c 'import sysconfig; print(sysconfig.get_paths()["pur # does not shadow the namespace package sage during the build. (cd "$SITEPACKAGESDIR" && rm -f sage/__init__.py) if [ "$SAGE_EDITABLE" = yes ]; then - # Check if we already have an editable install - if ls "$SITEPACKAGESDIR"/__editable__*sagemath* 2>/dev/null || ls "$SITEPACKAGESDIR"/sagemath*.egg-link 2>/dev/null; then - echo "Detected existing editable install - performing incremental build only" + # Check if this is an incremental build by looking for existing editable install + if python3 -c "import importlib.metadata; importlib.metadata.distribution('sagemath-standard')" 2>/dev/null && \ + python3 -c "import sage; import os; exit(0 if os.path.exists(os.path.join(os.path.dirname(sage.__file__), '..', 'setup.py')) else 1)" 2>/dev/null; then + echo "Detected existing editable install - performing incremental build" # Use setup.py build_ext --inplace for incremental compilation python3 setup.py build_ext --inplace || sdh_die "Error during incremental build" - # No reinstall needed - editable install is already in place + # No need to reinstall - editable install is already in place else - echo "No editable install found - performing initial editable install" + echo "Performing initial editable install" sdh_pip_editable_install . fi @@ -62,25 +63,12 @@ if [ "$SAGE_EDITABLE" = yes ]; then cd $SAGE_PKGS/sagelib/src && time sdh_build_and_store_wheel --no-build-isolation . fi else - # Check if this is an incremental build by looking for existing sagelib installation - if python3 -c "import importlib.metadata; importlib.metadata.distribution('sagemath-standard')" 2>/dev/null; then - echo "Detected existing sagelib installation - performing incremental build only" - # Use setup.py build_ext for incremental compilation only - python3 setup.py build_ext || sdh_die "Error during incremental build" - # For non-editable mode, we need to install to make changes available - python3 setup.py install || sdh_die "Error during incremental install" - elif [ "$SAGE_WHEELS" = yes ]; then - # Now implied: "$SAGE_WHEELS" = yes - # We should remove the egg-link that may have been installed previously. - (cd "$SITEPACKAGESDIR" && rm -f sagemath-standard.egg-link) - # Use --no-build-isolation to avoid rebuilds because of dependencies: - # Compiling sage/interfaces/sagespawn.pyx because it depends on /private/var/folders/38/wnh4gf1552g_crsjnv2vmmww0000gp/T/pip-build-env-609n5985/overlay/lib/python3.10/site-packages/Cython/Includes/posix/unistd.pxd - sdh_pip_install --no-build-isolation . - else - # Fallback: regular install for development - echo "Performing regular install" - python3 setup.py install || sdh_die "Error during install" - fi + # Now implied: "$SAGE_WHEELS" = yes + # We should remove the egg-link that may have been installed previously. + (cd "$SITEPACKAGESDIR" && rm -f sagemath-standard.egg-link) + # Use --no-build-isolation to avoid rebuilds because of dependencies: + # Compiling sage/interfaces/sagespawn.pyx because it depends on /private/var/folders/38/wnh4gf1552g_crsjnv2vmmww0000gp/T/pip-build-env-609n5985/overlay/lib/python3.10/site-packages/Cython/Includes/posix/unistd.pxd + sdh_pip_install --no-build-isolation . fi # Remove (potentially invalid) star import caches. From e8335291a75cb4c3b08940e80a5325fe40853ecd Mon Sep 17 00:00:00 2001 From: cxzhong Date: Mon, 18 Aug 2025 02:19:30 +0800 Subject: [PATCH 6/7] Add support for Python 3.13 in project metadata --- m4/pyproject_toml_metadata.m4 | 3 ++- m4/setup_cfg_metadata.m4 | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/m4/pyproject_toml_metadata.m4 b/m4/pyproject_toml_metadata.m4 index 5f39bd00077..582e17fd1a1 100644 --- a/m4/pyproject_toml_metadata.m4 +++ b/m4/pyproject_toml_metadata.m4 @@ -14,10 +14,11 @@ classifiers = [ "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", "Programming Language :: Python :: Implementation :: CPython", "Topic :: Scientific/Engineering :: Mathematics", ] -requires-python = ">=3.9, <3.13" +requires-python = ">=3.9, <3.14" [project.urls] download = "https://doc.sagemath.org/html/en/installation/index.html" diff --git a/m4/setup_cfg_metadata.m4 b/m4/setup_cfg_metadata.m4 index fb202433fcd..bd497c8dfe5 100644 --- a/m4/setup_cfg_metadata.m4 +++ b/m4/setup_cfg_metadata.m4 @@ -17,5 +17,6 @@ classifiers = Programming Language :: Python :: 3.10 Programming Language :: Python :: 3.11 Programming Language :: Python :: 3.12 + Programming Language :: Python :: 3.13 Programming Language :: Python :: Implementation :: CPython Topic :: Scientific/Engineering :: Mathematics From 4503938faa3437e62e3e634cc3bafbea16b6d954 Mon Sep 17 00:00:00 2001 From: cxzhong Date: Mon, 18 Aug 2025 03:43:46 +0800 Subject: [PATCH 7/7] Clean up build artifacts by removing build and egg-info directories during sagelib and distclean processes --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index b0c4cb2fa05..0ec4281cdd0 100644 --- a/Makefile +++ b/Makefile @@ -129,7 +129,7 @@ sagelib-clean: if [ -d "$(SAGE_SRC)" ]; then \ (cd "$(SAGE_SRC)" && \ rm -rf c_lib .cython_version cython_debug; \ - rm -rf build; find . -name '*.pyc' -o -name "*.so" | xargs rm -f; \ + rm -rf build *.egg-info; find . -name '*.pyc' -o -name "*.so" | xargs rm -f; \ rm -f $$(find . -name "*.pyx" | sed 's/\(.*\)[.]pyx$$/\1.c \1.cpp/'); \ cd sage/ext/interpreters/ && rm -f *.so *.c *.h *.py* *.pxd) \ && (cd "$(SAGE_ROOT)/build/pkgs/sagelib/src/" && rm -rf build); \ @@ -173,7 +173,7 @@ bdist-clean: clean distclean: build-clean $(MAKE) misc-clean @echo "Deleting all remaining output from build system ..." - rm -rf local + rm -rf local *.egg-info rm -f src/bin/sage-env-config rm -f prefix venv