diff --git a/.devcontainer/onCreate-conda.sh b/.devcontainer/onCreate-conda.sh index 852b8d880fb..8a11e999ee9 100755 --- a/.devcontainer/onCreate-conda.sh +++ b/.devcontainer/onCreate-conda.sh @@ -10,4 +10,4 @@ mamba env create -y --file environment-3.11-linux.yml || mamba env update --file conda init bash # Build sage -conda run -n sage-dev pip install --no-build-isolation -v -v -e . --config-settings=build-dir="build/conda-cp311" +conda run -n sage-dev pip install --no-build-isolation -v -v --config-settings=build-dir="build/conda-cp311" --editable . diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index a6b7691a817..50457ccf88c 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -74,6 +74,8 @@ env: FROM_DOCKER_TARGET: "with-targets" FROM_DOCKER_TAG: ${{ github.event.inputs.docker_tag || 'dev'}} EXTRA_CONFIGURE_ARGS: --enable-fat-binary + # Enable editable installs for faster incremental builds + SAGE_EDITABLE: yes jobs: test-long: diff --git a/.github/workflows/ci-meson.yml b/.github/workflows/ci-meson.yml index 30ae0439432..2464867b606 100644 --- a/.github/workflows/ci-meson.yml +++ b/.github/workflows/ci-meson.yml @@ -101,6 +101,30 @@ jobs: activate-environment: sage-dev environment-file: environment-${{ matrix.python }}-${{ startsWith(matrix.os, 'macos') && (startsWith(runner.arch, 'ARM') && 'macos' || 'macos-x86_64') || startsWith(matrix.os, 'ubuntu') && 'linux' || 'win' }}.yml + - name: Install build dependencies + if: runner.os == 'Linux' + shell: bash -l {0} + run: | + # Ensure essential build tools are available for Linux builds + sudo apt-get update + sudo apt-get install -y build-essential gfortran libtool-bin + + - name: Install build dependencies (macOS) + if: runner.os == 'macOS' + shell: bash -l {0} + run: | + # Ensure build dependencies are properly installed on macOS + # First update conda and pip to latest versions + conda update -n base –y conda + # Install/update essential build tools in the correct order + conda activate sage-dev + pip install --upgrade pip + pip install --upgrade setuptools wheel + pip install --upgrade meson-python + # Verify installations + python -c "import setuptools; print(f'setuptools: {setuptools.__version__}')" + python -c "import mesonpy; print(f'meson-python: {mesonpy.__version__}')" + # Sometimes the conda setup fails due to network issues. # This is a workaround to retry the setup step if it fails. # Workaround for https://github.com/conda-incubator/setup-miniconda/issues/129 @@ -123,20 +147,63 @@ jobs: conda info conda list + - name: Clean build artifacts + shell: bash -l {0} + run: | + # Clean any previous build artifacts that might cause issues + rm -rf build/ dist/ *.egg-info builddir/ + find . -name "*.pyc" -delete + find . -name "__pycache__" -type d -exec rm -rf {} + 2>/dev/null || true + + - name: Verify Python environment + shell: bash -l {0} + run: | + # Verify the Python environment is correctly set up + python --version + pip --version + python -c "import sys; print(f'Python executable: {sys.executable}')" + python -c "import sysconfig; print(f'Python include: {sysconfig.get_path(\"include\")}')" + # Test that we can import required build dependencies + python -c "import setuptools, wheel, mesonpy; print('Build dependencies OK')" || { + echo "Build dependencies missing, installing..." + pip install --upgrade setuptools wheel meson-python + } + - name: Build shell: bash -l {0} run: | if [[ "$RUNNER_OS" != "Windows" ]]; then + # Clean environment to avoid conflicts + unset CFLAGS CXXFLAGS LDFLAGS + # Set up ccache for faster builds export PATH="/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH" - export CC="ccache $CC" - export CXX="ccache $CXX" + # Only use ccache if the base compilers are available + if command -v gcc >/dev/null 2>&1; then + export CC="ccache gcc" + fi + if command -v g++ >/dev/null 2>&1; then + export CXX="ccache g++" + fi else export LIB="$LIB;$CONDA_PREFIX\\Library\\lib" export INCLUDE="$INCLUDE;$CONDA_PREFIX\\Library\\include" fi + # Debug: Show environment before build + echo "=== Build Environment ===" + echo "Python: $(python --version)" + echo "Pip: $(pip --version)" + echo "Working directory: $(pwd)" + echo "Python path: $PYTHONPATH" + # Use --no-deps and pip check below to verify that all necessary dependencies are installed via conda - pip install --no-build-isolation --no-deps --config-settings=builddir=builddir ${{ matrix.editable && '--editable' || '' }} . -v + if [[ "${{ matrix.editable }}" == "true" ]]; then + echo "Building in editable mode..." + pip install --no-build-isolation --no-deps --config-settings=builddir=builddir --editable . -v + else + echo "Building in standard mode..." + pip install --no-build-isolation --no-deps --config-settings=builddir=builddir . -v + fi - name: Check update-meson # this step must be after build, because meson.build creates a number of __init__.py files @@ -144,12 +211,27 @@ jobs: shell: bash -l {0} if: matrix.tests == 'all' run: | + # Store current git state + git add . + git stash push -m "Pre-update-meson state" + + # Run update-meson python tools/update-meson.py - if ! ./tools/test-git-no-uncommitted-changes; then - git add --intent-to-add . # also show newly created files in git diff - git status - git diff - false + + # Check if update-meson made any changes to tracked files + if ! git diff --quiet HEAD; then + echo "update-meson.py made changes to tracked files:" + git diff HEAD + echo "Please run 'python tools/update-meson.py' and commit the changes." + exit 1 + fi + + # Check for new untracked files that should be committed + if [ -n "$(git ls-files --others --exclude-standard)" ]; then + echo "update-meson.py created new files that may need to be committed:" + git ls-files --others --exclude-standard + echo "If these files should be tracked, please add and commit them." + # Don't fail for new files, just warn fi - name: Verify dependencies diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8d56c4fab0e..1e7c1ad607a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -67,15 +67,16 @@ jobs: # Install build dependencies manually as workaround for https://github.com/astral-sh/uv/issues/1516 uv pip install \ meson-python \ + "setuptools >=68.1.1" \ "cypari2 >=2.2.1" \ "cysignals >=1.11.2, != 1.12.0" \ "cython >=3.0, != 3.0.3, < 3.1.0" \ "gmpy2 ~=2.1.b999" \ memory_allocator \ "numpy >=1.25" \ - jinja2 \ - setuptools - uv sync --frozen --inexact --no-build-isolation -v + jinja2 + # Use editable install for faster incremental builds + MESONPY_EDITABLE_VERBOSE=1 uv sync --frozen --inexact --no-build-isolation -v - name: Test run: | diff --git a/.github/workflows/doc-build-pdf.yml b/.github/workflows/doc-build-pdf.yml index 9e2726751cd..576874d0832 100644 --- a/.github/workflows/doc-build-pdf.yml +++ b/.github/workflows/doc-build-pdf.yml @@ -28,6 +28,8 @@ env: FROM_DOCKER_TARGET: "with-targets" FROM_DOCKER_TAG: ${{ github.event.inputs.docker_tag || 'dev'}} EXTRA_CONFIGURE_ARGS: --enable-fat-binary + # Enable editable installs for faster incremental builds + SAGE_EDITABLE: yes jobs: build-doc-pdf: diff --git a/.github/workflows/doc-build.yml b/.github/workflows/doc-build.yml index c56e9a06346..f2fc8f09e19 100644 --- a/.github/workflows/doc-build.yml +++ b/.github/workflows/doc-build.yml @@ -62,14 +62,30 @@ jobs: channel-priority: true activate-environment: sage-dev environment-file: environment-${{ env.PYTHON_VERSION }}-linux.yml + + - name: Install build dependencies + shell: bash -l {0} + run: | + # Ensure essential build tools are available + sudo apt-get update + sudo apt-get install -y build-essential gfortran libtool-bin - name: Build Sage shell: bash -l {0} run: | + # Clean environment to avoid conflicts + unset CFLAGS CXXFLAGS LDFLAGS + # Set up ccache for faster builds export PATH="/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH" - export CC="ccache $CC" - export CXX="ccache $CXX" - pip install --no-build-isolation --config-settings=builddir=builddir . -v + # Only use ccache if the base compilers are available + if command -v gcc >/dev/null 2>&1; then + export CC="ccache gcc" + fi + if command -v g++ >/dev/null 2>&1; then + export CXX="ccache g++" + fi + # Use editable install for faster incremental builds + MESONPY_EDITABLE_VERBOSE=1 pip install --no-build-isolation --config-settings=builddir=builddir --editable . -v # # For pull requests diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index a65c5582597..b6351df5aa0 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -121,6 +121,8 @@ jobs: FROM_DOCKER_TAG: ${{ inputs.from_docker_tag }} EXTRA_CONFIGURE_ARGS: --enable-fat-binary EXTRA_SAGE_PACKAGES: ${{ inputs.extra_sage_packages }} + # Enable editable installs for faster incremental builds + SAGE_EDITABLE: yes steps: - name: Maximize build disk space uses: easimon/maximize-build-space@v10 diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index 57af4d9463e..38ac43b25ac 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -136,7 +136,7 @@ jobs: ;; esac (sleep ${{ inputs.timeout }}; pkill make) & - MAKE="make -j12" EXTRA_SAGE_PACKAGES="${{ inputs.extra_sage_packages }}" "${{ steps.python.outputs.python-path }}" -m pipx run tox -e $TOX_ENV -- SAGE_NUM_THREADS=6 $TARGETS + MAKE="make -j12" EXTRA_SAGE_PACKAGES="${{ inputs.extra_sage_packages }}" SAGE_EDITABLE=yes "${{ steps.python.outputs.python-path }}" -m pipx run tox -e $TOX_ENV -- SAGE_NUM_THREADS=6 $TARGETS - name: Prepare logs artifact run: | mkdir -p "artifacts/$LOGS_ARTIFACT_NAME"; cp -r .tox/*/log "artifacts/$LOGS_ARTIFACT_NAME" diff --git a/.gitpod.yml b/.gitpod.yml index 554a5c41f4b..b2ea23520c6 100644 --- a/.gitpod.yml +++ b/.gitpod.yml @@ -11,7 +11,7 @@ tasks: && conda config --append envs_dirs $(pwd) && conda activate $(pwd)/venv && ./bootstrap - && pip install --no-build-isolation -v -v -e ./src + && pip install --no-build-isolation -v -v --editable ./src # Activate conda environment, set up Trac remote # RestructuredText extension recommends python extension, although we have already installed it # So disable the recommendation dialog diff --git a/.vscode/settings.json b/.vscode/settings.json index 887f416bfc4..2f886f6a611 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -119,5 +119,15 @@ // Use the Meson build system for C/C++ files "C_Cpp.default.configurationProvider": "mesonbuild.mesonbuild", // Use the compile_commands.json file generated by Meson for IntelliSense - "C_Cpp.default.compileCommands": "${workspaceFolder}/builddir/compile_commands.json" + "C_Cpp.default.compileCommands": "${workspaceFolder}/builddir/compile_commands.json", + // Environment variables for SageMath development + "terminal.integrated.env.linux": { + "MESONPY_EDITABLE_VERBOSE": "1" + }, + "terminal.integrated.env.osx": { + "MESONPY_EDITABLE_VERBOSE": "1" + }, + "terminal.integrated.env.windows": { + "MESONPY_EDITABLE_VERBOSE": "1" + } } diff --git a/build/bin/sage-spkg b/build/bin/sage-spkg index 1ea8ad70b93..5d42e33bb73 100755 --- a/build/bin/sage-spkg +++ b/build/bin/sage-spkg @@ -177,7 +177,7 @@ fi . sage-build-env-config . sage-build-env || exit_with_error_msg "Error setting environment variables by sourcing sage-build-env" -# Remove '.' from PYTHONPATH, to avoid trouble with setuptools / easy_install +# Remove '.' from PYTHONPATH, to avoid trouble with setuptools / pip # (cf. #10192, #10176): if [ -n "$PYTHONPATH" ]; then # We also collapse multiple slashs into a single one (first substitution), diff --git a/build/pkgs/beniget/checksums.ini b/build/pkgs/beniget/checksums.ini index a199e02756e..907a4cd5720 100644 --- a/build/pkgs/beniget/checksums.ini +++ b/build/pkgs/beniget/checksums.ini @@ -1,4 +1,4 @@ tarball=beniget-VERSION.tar.gz -sha1=0167f16d17fbd61b91e620bca07e4ec7054ce51d -sha256=75554b3b8ad0553ce2f607627dad3d95c60c441189875b98e097528f8e23ac0c +sha1=95233c191f0ea8486a8ef0cf40d9c5a9838f2439 +sha256=a0258537e65e7e14ec33a86802f865a667f949bb6c73646d55e42f7c45a052ae upstream_url=https://files.pythonhosted.org/packages/source/b/beniget/beniget-VERSION.tar.gz diff --git a/build/pkgs/beniget/package-version.txt b/build/pkgs/beniget/package-version.txt index 267577d47e4..58d4788bbc3 100644 --- a/build/pkgs/beniget/package-version.txt +++ b/build/pkgs/beniget/package-version.txt @@ -1 +1 @@ -0.4.1 +0.4.2.post1 diff --git a/build/pkgs/cysignals/checksums.ini b/build/pkgs/cysignals/checksums.ini index 9c6648af170..1998da9e36f 100644 --- a/build/pkgs/cysignals/checksums.ini +++ b/build/pkgs/cysignals/checksums.ini @@ -1,4 +1,4 @@ tarball=cysignals-VERSION.tar.gz -sha1=e285e209a3a5f9469cb5ade746c518cd3a600a9b -sha256=89f7626dbf29db5ab3d6eff15a89978f4eb5193c320e9099bcc157dacdefd1eb +sha1=d3f23d9d82aab06939996f8cbc881a1c529cab98 +sha256=4aefa3b35eb036cb40b2b948df84725976b987895338204f64550e2d63891f5f upstream_url=https://files.pythonhosted.org/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 81f363239f5..89c881bc9cb 100644 --- a/build/pkgs/cysignals/package-version.txt +++ b/build/pkgs/cysignals/package-version.txt @@ -1 +1 @@ -1.12.3 +1.12.4 diff --git a/build/pkgs/cython/checksums.ini b/build/pkgs/cython/checksums.ini index 3eb199915d7..148c3b8bfe9 100644 --- a/build/pkgs/cython/checksums.ini +++ b/build/pkgs/cython/checksums.ini @@ -1,4 +1,4 @@ tarball=cython-VERSION.tar.gz -sha1=f692b0c6f209b75b6bbd69bdbd57fac23785c23e -sha256=7146dd2af8682b4ca61331851e6aebce9fe5158e75300343f80c07ca80b1faff +sha1=3bd5a99e283297a423bb9bb1ab9765bb4bfde86e +sha256=10ee785e42328924b78f75a74f66a813cb956b4a9bc91c44816d089d5934c089 upstream_url=https://files.pythonhosted.org/packages/source/c/cython/cython-VERSION.tar.gz diff --git a/build/pkgs/cython/package-version.txt b/build/pkgs/cython/package-version.txt index 778bf95c00f..ff365e06b95 100644 --- a/build/pkgs/cython/package-version.txt +++ b/build/pkgs/cython/package-version.txt @@ -1 +1 @@ -3.0.11 +3.1.3 diff --git a/build/pkgs/gast/checksums.ini b/build/pkgs/gast/checksums.ini index 83cdc0ef554..6a48e60d824 100644 --- a/build/pkgs/gast/checksums.ini +++ b/build/pkgs/gast/checksums.ini @@ -1,4 +1,4 @@ tarball=gast-VERSION.tar.gz -sha1=6c113cf8d33cc654d33210335103485ab41d3dbb -sha256=9c270fe5f4b130969b54174de7db4e764b09b4f7f67ccfc32480e29f78348d97 +sha1=6ff8b1105c331ac55d1f9fa389b7486b9f8c9c07 +sha256=88fc5300d32c7ac6ca7b515310862f71e6fdf2c029bbec7c66c0f5dd47b6b1fb upstream_url=https://files.pythonhosted.org/packages/source/g/gast/gast-VERSION.tar.gz diff --git a/build/pkgs/gast/package-version.txt b/build/pkgs/gast/package-version.txt index 7d8568351b4..a918a2aa18d 100644 --- a/build/pkgs/gast/package-version.txt +++ b/build/pkgs/gast/package-version.txt @@ -1 +1 @@ -0.5.4 +0.6.0 diff --git a/build/pkgs/pip/SPKG.rst b/build/pkgs/pip/SPKG.rst index 837967428b7..79dfcc2cc8e 100644 --- a/build/pkgs/pip/SPKG.rst +++ b/build/pkgs/pip/SPKG.rst @@ -1,12 +1,12 @@ -pip: Tool for installing and managing Python packages -===================================================== +pip +=== Description ----------- -This package installs pip, the tool for installing and managing Python -packages, such as those found in the Python Package Index. It’s a -replacement for easy_install. +This package installs pip, the standard tool for installing and managing Python +packages, such as those found in the Python Package Index. It has replaced +the deprecated easy_install tool. License ------- @@ -23,4 +23,3 @@ Upstream Contact - Bug Tracking: https://github.com/pypa/pip/issues - Mailing list: http://groups.google.com/group/python-virtualenv - Docs: https://pip.pypa.io/ - diff --git a/build/pkgs/pythran/checksums.ini b/build/pkgs/pythran/checksums.ini index ebb9201d099..3f7fc13ab87 100644 --- a/build/pkgs/pythran/checksums.ini +++ b/build/pkgs/pythran/checksums.ini @@ -1,4 +1,4 @@ tarball=pythran-VERSION-py3-none-any.whl -sha1=2341d42c014f88318f447083c62e8d3953b04ac2 -sha256=be569cc2817b625ccd2c8f74fa3c93806f245c65fadc282c26a9f546ebd34cfa +sha1=5e68b54f525e1f7de6e73aa3e897f5f21652bd1d +sha256=405ecf2100d4926d1a15640c36bd1b19a560386653d0ee4d5234f9421ef4034b upstream_url=https://files.pythonhosted.org/packages/py3/p/pythran/pythran-VERSION-py3-none-any.whl diff --git a/build/pkgs/pythran/package-version.txt b/build/pkgs/pythran/package-version.txt index c5523bd09b1..66333910a4b 100644 --- a/build/pkgs/pythran/package-version.txt +++ b/build/pkgs/pythran/package-version.txt @@ -1 +1 @@ -0.17.0 +0.18.0 diff --git a/build/pkgs/setuptools/checksums.ini b/build/pkgs/setuptools/checksums.ini index 13bcfce0429..cc48bd426de 100644 --- a/build/pkgs/setuptools/checksums.ini +++ b/build/pkgs/setuptools/checksums.ini @@ -1,4 +1,4 @@ tarball=setuptools-VERSION-py3-none-any.whl -sha1=3756539d45341ca5cec9e2dfe11539faa066f5cd -sha256=b208925fcb9f7af924ed2dc04708ea89791e24bde0d3020b27df0e116088b34e +sha1=f82aabaab9ae429e91d2b0d748ecd2c0b07c5de8 +sha256=062d34222ad13e0cc312a4c02d73f059e86a4acbfbdea8f8f76b28c99f306922 upstream_url=https://files.pythonhosted.org/packages/py3/s/setuptools/setuptools-VERSION-py3-none-any.whl diff --git a/build/pkgs/setuptools/package-version.txt b/build/pkgs/setuptools/package-version.txt index 153e4cd6210..6585caca14a 100644 --- a/build/pkgs/setuptools/package-version.txt +++ b/build/pkgs/setuptools/package-version.txt @@ -1 +1 @@ -73.0.1 +80.9.0 diff --git a/build/pkgs/setuptools_scm/checksums.ini b/build/pkgs/setuptools_scm/checksums.ini index 553d3df6614..f31b59216ec 100644 --- a/build/pkgs/setuptools_scm/checksums.ini +++ b/build/pkgs/setuptools_scm/checksums.ini @@ -1,4 +1,4 @@ tarball=setuptools_scm-VERSION-py3-none-any.whl -sha1=be606b6acb67714b96e9e1e9a9944feaca504e44 -sha256=897a3226a6fd4a6eb2f068745e49733261a21f70b1bb28fce0339feb978d9af3 +sha1=29b1eb2fa08075564f062c354eab106380ad16e6 +sha256=332ca0d43791b818b841213e76b1971b7711a960761c5bea5fc5cdb5196fbce3 upstream_url=https://files.pythonhosted.org/packages/py3/s/setuptools_scm/setuptools_scm-VERSION-py3-none-any.whl diff --git a/build/pkgs/setuptools_scm/package-version.txt b/build/pkgs/setuptools_scm/package-version.txt index 8104cabd36f..56b6be4ebb2 100644 --- a/build/pkgs/setuptools_scm/package-version.txt +++ b/build/pkgs/setuptools_scm/package-version.txt @@ -1 +1 @@ -8.1.0 +8.3.1 diff --git a/docker/Dockerfile b/docker/Dockerfile index 101f50b5860..ccae70f6704 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -189,6 +189,9 @@ ENV SAGE_FAT_BINARY yes # Just to be sure Sage doesn't try to build its own GCC (even though # it shouldn't with a recent GCC package from the system and with gfortran) ENV SAGE_INSTALL_GCC no +# Enable editable installs for faster incremental builds +ARG SAGE_EDITABLE="yes" +ENV SAGE_EDITABLE $SAGE_EDITABLE # Set MAKEFLAGS and SAGE_NUM_THREADS to build things in parallel during the # docker build. Note that these do not leak into the sagemath and sagemath-dev # images. @@ -197,8 +200,8 @@ ENV MAKEFLAGS $MAKEFLAGS ARG SAGE_NUM_THREADS="2" ENV SAGE_NUM_THREADS $SAGE_NUM_THREADS RUN make configure -# Old default before https://github.com/sagemath/sage/issues/32406 -RUN ./configure --disable-editable +# Enable editable installs by default (SAGE_EDITABLE=yes is the default in configure.ac) +RUN ./configure RUN make build ################################################################################ diff --git a/pkgs/sage-conf_pypi/setup.py b/pkgs/sage-conf_pypi/setup.py index 54dcecf7e17..9d783033b0e 100644 --- a/pkgs/sage-conf_pypi/setup.py +++ b/pkgs/sage-conf_pypi/setup.py @@ -7,7 +7,7 @@ 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_scripts import build_scripts as setuptools_build_scripts # Use setuptools instead of distutils from setuptools.command.build_py import build_py as setuptools_build_py from setuptools.command.editable_wheel import editable_wheel as setuptools_editable_wheel from setuptools.errors import SetupError @@ -111,18 +111,18 @@ def ignore(path, names): ignore=ignore) # will fail if already exists except Exception as e: raise SetupError(f"the directory SAGE_ROOT={SAGE_ROOT} already exists but it is not configured ({e}). " - "Please either remove it and try again, or install in editable mode (pip install -e).") + "Please either remove it and try again, or install in editable mode (pip install --editable).") return SAGE_ROOT -class build_scripts(distutils_build_scripts): +class build_scripts(setuptools_build_scripts): def run(self): self.distribution.scripts.append(os.path.join('bin', 'sage-env-config')) if not self.distribution.entry_points: self.entry_points = self.distribution.entry_points = dict() - distutils_build_scripts.run(self) + setuptools_build_scripts.run(self) class editable_wheel(setuptools_editable_wheel): diff --git a/pkgs/sage-docbuild/pyproject.toml b/pkgs/sage-docbuild/pyproject.toml index bcfdb94d040..9137055bc51 100644 --- a/pkgs/sage-docbuild/pyproject.toml +++ b/pkgs/sage-docbuild/pyproject.toml @@ -1,5 +1,5 @@ [build-system] -requires = ["setuptools>=61.2"] +requires = ["setuptools>=68.1.1"] build-backend = "setuptools.build_meta" [project] diff --git a/pkgs/sage-setup/pyproject.toml b/pkgs/sage-setup/pyproject.toml index 820da4fbbeb..1d03b66980b 100644 --- a/pkgs/sage-setup/pyproject.toml +++ b/pkgs/sage-setup/pyproject.toml @@ -1,5 +1,5 @@ [build-system] -requires = ["setuptools>=61.2"] +requires = ["setuptools>=68.1.1"] build-backend = "setuptools.build_meta" [project] diff --git a/pkgs/sagemath-bliss/setup.py b/pkgs/sagemath-bliss/setup.py index 40f26bd8ead..eb3d15e92c8 100644 --- a/pkgs/sagemath-bliss/setup.py +++ b/pkgs/sagemath-bliss/setup.py @@ -1,8 +1,17 @@ #!/usr/bin/env python -from distutils import log +import logging +import sys from setuptools import setup +# Configure logging with simple format showing only level and message +logging.basicConfig( + level=logging.INFO, + format='%(levelname)s: %(message)s', + stream=sys.stdout +) +logger = logging.getLogger(__name__) + # Work around a Cython problem in Python 3.8.x on macOS # https://github.com/cython/cython/issues/3262 import os @@ -53,9 +62,9 @@ python_packages, python_modules, cython_modules = find_python_sources( '.', ['sage'], distributions=['sagemath-bliss']) -log.warn('python_packages = {0}'.format(python_packages)) -log.warn('python_modules = {0}'.format(python_modules)) -log.warn('cython_modules = {0}'.format(cython_modules)) +logger.warn('python_packages = {0}'.format(python_packages)) +logger.warn('python_modules = {0}'.format(python_modules)) +logger.warn('cython_modules = {0}'.format(cython_modules)) setup( cmdclass = cmdclass, diff --git a/pkgs/sagemath-coxeter3/setup.py b/pkgs/sagemath-coxeter3/setup.py index 1979cf43a46..2e5d5e27403 100644 --- a/pkgs/sagemath-coxeter3/setup.py +++ b/pkgs/sagemath-coxeter3/setup.py @@ -53,9 +53,9 @@ python_packages, python_modules, cython_modules = find_python_sources( '.', ['sage'], distributions=['sagemath-coxeter3']) -log.warn('python_packages = {0}'.format(python_packages)) -log.warn('python_modules = {0}'.format(python_modules)) -log.warn('cython_modules = {0}'.format(cython_modules)) +logger.warning('python_packages = {0}'.format(python_packages)) +logger.warning('python_modules = {0}'.format(python_modules)) +logger.warning('cython_modules = {0}'.format(cython_modules)) setup( cmdclass = cmdclass, diff --git a/pkgs/sagemath-mcqd/setup.py b/pkgs/sagemath-mcqd/setup.py index 8cbcf6477c2..28120a85a77 100644 --- a/pkgs/sagemath-mcqd/setup.py +++ b/pkgs/sagemath-mcqd/setup.py @@ -1,8 +1,17 @@ #!/usr/bin/env python -from distutils import log +import logging +import sys from setuptools import setup +# Configure logging with simple format showing only level and message +logging.basicConfig( + level=logging.INFO, + format='%(levelname)s: %(message)s', + stream=sys.stdout +) +logger = logging.getLogger(__name__) + # Work around a Cython problem in Python 3.8.x on macOS # https://github.com/cython/cython/issues/3262 import os @@ -53,9 +62,9 @@ python_packages, python_modules, cython_modules = find_python_sources( '.', ['sage'], distributions=['sagemath-mcqd']) -log.warn('python_packages = {0}'.format(python_packages)) -log.warn('python_modules = {0}'.format(python_modules)) -log.warn('cython_modules = {0}'.format(cython_modules)) +logger.warning('python_packages = {0}'.format(python_packages)) +logger.warning('python_modules = {0}'.format(python_modules)) +logger.warning('cython_modules = {0}'.format(cython_modules)) setup( cmdclass = cmdclass, diff --git a/pkgs/sagemath-meataxe/setup.py b/pkgs/sagemath-meataxe/setup.py index f8e3f30ea9b..57c58857199 100644 --- a/pkgs/sagemath-meataxe/setup.py +++ b/pkgs/sagemath-meataxe/setup.py @@ -1,8 +1,14 @@ #!/usr/bin/env python -from distutils import log +import logging from setuptools import setup +# Set up logging with simplified format +logging.basicConfig( + level=logging.INFO, + format='%(levelname)s: %(message)s' +) +logger = logging.getLogger(__name__) # Work around a Cython problem in Python 3.8.x on macOS # https://github.com/cython/cython/issues/3262 import os @@ -53,9 +59,9 @@ python_packages, python_modules, cython_modules = find_python_sources( '.', ['sage'], distributions=['sagemath-meataxe']) -log.warn('python_packages = {0}'.format(python_packages)) -log.warn('python_modules = {0}'.format(python_modules)) -log.warn('cython_modules = {0}'.format(cython_modules)) +logger.warning('python_packages = {0}'.format(python_packages)) +logger.warning('python_modules = {0}'.format(python_modules)) +logger.warning('cython_modules = {0}'.format(cython_modules)) setup( cmdclass = cmdclass, diff --git a/pkgs/sagemath-objects/setup.py b/pkgs/sagemath-objects/setup.py index ad114fa0de1..70a509ff221 100644 --- a/pkgs/sagemath-objects/setup.py +++ b/pkgs/sagemath-objects/setup.py @@ -1,8 +1,12 @@ #!/usr/bin/env python -from distutils import log +import logging from setuptools import setup +# Set up logging +logging.basicConfig(level=logging.INFO) +logger = logging.getLogger(__name__) + # Work around a Cython problem in Python 3.8.x on macOS # https://github.com/cython/cython/issues/3262 import os @@ -33,9 +37,9 @@ python_packages, python_modules, cython_modules = find_python_sources( '.', ['sage']) # for now, we do the filtering using MANIFEST -log.warn('python_packages = {0}'.format(python_packages)) -log.warn('python_modules = {0}'.format(python_modules)) -log.warn('cython_modules = {0}'.format(cython_modules)) +logger.warning('python_packages = {0}'.format(python_packages)) +logger.warning('python_modules = {0}'.format(python_modules)) +logger.warning('cython_modules = {0}'.format(cython_modules)) setup( cmdclass = cmdclass, diff --git a/pkgs/sagemath-sirocco/setup.py b/pkgs/sagemath-sirocco/setup.py index 9d82bfebcd8..2104e022163 100644 --- a/pkgs/sagemath-sirocco/setup.py +++ b/pkgs/sagemath-sirocco/setup.py @@ -53,9 +53,9 @@ python_packages, python_modules, cython_modules = find_python_sources( '.', ['sage'], distributions=['sagemath-sirocco']) -log.warn('python_packages = {0}'.format(python_packages)) -log.warn('python_modules = {0}'.format(python_modules)) -log.warn('cython_modules = {0}'.format(cython_modules)) +logger.warning('python_packages = {0}'.format(python_packages)) +logger.warning('python_modules = {0}'.format(python_modules)) +logger.warning('cython_modules = {0}'.format(cython_modules)) setup( cmdclass = cmdclass, diff --git a/pkgs/sagemath-standard/setup.py b/pkgs/sagemath-standard/setup.py index 95c1609cf1c..942139a4314 100755 --- a/pkgs/sagemath-standard/setup.py +++ b/pkgs/sagemath-standard/setup.py @@ -1,14 +1,22 @@ #!/usr/bin/env python +import logging import os import sys import time # Import setuptools before importing distutils, so that setuptools # can replace distutils by its own vendored copy. import setuptools -from distutils import log from setuptools import setup +# Configure logging with simple format showing only level and message +logging.basicConfig( + level=logging.INFO, + format='%(levelname)s: %(message)s', + stream=sys.stdout +) +logger = logging.getLogger(__name__) + # Work around a Cython problem in Python 3.8.x on macOS # https://github.com/cython/cython/issues/3262 if os.uname().sysname == 'Darwin': @@ -65,7 +73,7 @@ if any(x in sys.argv for x in ['build', 'build_ext', 'bdist_wheel', 'install']): - log.info("Generating auto-generated sources") + logger.info("Generating auto-generated sources") from sage_setup.autogen import autogen_all autogen_all() @@ -77,14 +85,14 @@ 'sagemath-objects', 'sagemath-repl', ''] -log.warn('distributions = {0}'.format(distributions)) +logger.warn('distributions = {0}'.format(distributions)) from sage_setup.find import find_python_sources python_packages, python_modules, cython_modules = find_python_sources( SAGE_SRC, ['sage'], distributions=distributions) -log.debug('python_packages = {0}'.format(python_packages)) -log.debug('python_modules = {0}'.format(python_modules)) -log.debug('cython_modules = {0}'.format(cython_modules)) +logger.debug('python_packages = {0}'.format(python_packages)) +logger.debug('python_modules = {0}'.format(python_modules)) +logger.debug('cython_modules = {0}'.format(cython_modules)) print("Discovered Python/Cython sources, time: %.2f seconds." % (time.time() - t)) diff --git a/pkgs/sagemath-tdlib/setup.py b/pkgs/sagemath-tdlib/setup.py index 0d6e1c1db28..70f394df73c 100644 --- a/pkgs/sagemath-tdlib/setup.py +++ b/pkgs/sagemath-tdlib/setup.py @@ -1,8 +1,17 @@ #!/usr/bin/env python -from distutils import log +import logging +import sys from setuptools import setup +# Configure logging with simple format showing only level and message +logging.basicConfig( + level=logging.INFO, + format='%(levelname)s: %(message)s', + stream=sys.stdout +) +logger = logging.getLogger(__name__) + # Work around a Cython problem in Python 3.8.x on macOS # https://github.com/cython/cython/issues/3262 import os @@ -53,9 +62,9 @@ python_packages, python_modules, cython_modules = find_python_sources( '.', ['sage'], distributions=['sagemath-tdlib']) -log.warn('python_packages = {0}'.format(python_packages)) -log.warn('python_modules = {0}'.format(python_modules)) -log.warn('cython_modules = {0}'.format(cython_modules)) +logger.warning('python_packages = {0}'.format(python_packages)) +logger.warning('python_modules = {0}'.format(python_modules)) +logger.warning('cython_modules = {0}'.format(cython_modules)) setup( cmdclass = cmdclass, diff --git a/pyproject.toml b/pyproject.toml index d4d023ae190..ced9401b1a1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -2,7 +2,9 @@ build-backend = 'mesonpy' # Minimum requirements for the build system to execute. requires = [ - 'meson-python', + 'meson-python >=0.13.0', # Ensure compatible version + 'setuptools >=68.1.1', # Modern setuptools for compatibility with latest tools + 'wheel', # Required for metadata generation 'cypari2 >=2.2.1; sys_platform != "win32"', # Exclude 1.12.0 because of https://github.com/sagemath/cysignals/issues/212 'cysignals >=1.11.2, != 1.12.0', @@ -24,6 +26,11 @@ install = ['--skip-subprojects'] # Ensure that ``library`` targets are built as static, and nothing gets installed setup = ['--default-library=static'] +# Development Note: For fast incremental development, install in editable mode: +# pip install --no-build-isolation --editable . +# This enables automatic recompilation of only changed files when running ./sage +# Set MESONPY_EDITABLE_VERBOSE=1 to see recompilation messages + [project] name = "sagemath" description = "Sage: Open Source Mathematics Software: Standard Python Library" @@ -244,3 +251,15 @@ ignore = [ [tool.uv] # Don't use build isolation for sage (it's incompatible with meson-python's editable install) no-build-isolation-package = ["sagemath"] + +# Note: setuptools configuration is included for compatibility with tools +# that may reference it, but the actual build system is meson-python +[tool.setuptools] +# Modern setuptools configuration for better tool compatibility +zip-safe = false +include-package-data = true + +[tool.setuptools.packages.find] +# Ensure setuptools can find packages properly +where = ["src"] +include = ["sage*"] diff --git a/src/doc/en/developer/packaging.rst b/src/doc/en/developer/packaging.rst index bdfae915090..c714b5c78c5 100644 --- a/src/doc/en/developer/packaging.rst +++ b/src/doc/en/developer/packaging.rst @@ -449,7 +449,7 @@ begin with ``sdh_``, which stands for "Sage-distribution helper". creating a wheel file in ``dist/``, followed by ``sdh_store_and_pip_install_wheel`` (see below). -- ``sdh_pip_editable_install [...]``: The equivalent of running ``pip install -e`` +- ``sdh_pip_editable_install [...]``: The equivalent of running ``pip install --editable`` with the given arguments, as well as additional default arguments used for installing packages into Sage with pip. The last argument must be ``.`` to indicate installation from the current directory. diff --git a/src/requirements.txt.m4 b/src/requirements.txt.m4 index 34c42860cf1..2ef47218579 100644 --- a/src/requirements.txt.m4 +++ b/src/requirements.txt.m4 @@ -6,7 +6,7 @@ ## (sage-sh) $ python3 -m venv venv1 ## (sage-sh) $ source venv1/bin/activate ## (venv1) (sage-sh) $ pip install -r requirements.txt -## (venv1) (sage-sh) $ pip install -e . +## (venv1) (sage-sh) $ pip install --editable . dnl FIXME: Including the whole package-version.txt does not work for packages that have a patchlevel.... dnl We need a better tool to format this information. diff --git a/src/sage/misc/dev_tools.py b/src/sage/misc/dev_tools.py index 90f41f8b0f4..f2f6935d9c5 100644 --- a/src/sage/misc/dev_tools.py +++ b/src/sage/misc/dev_tools.py @@ -46,11 +46,11 @@ def runsnake(command): :func:`runsnake` requires the program ``runsnake``. Due to non trivial dependencies (python-wxgtk, ...), installing it within the Sage distribution is unpractical. Hence, we recommend installing - it with the system wide Python. On Ubuntu 10.10, this can be done + it with the system wide Python. On Ubuntu, this can be done with:: - > sudo apt-get install python-profiler python-wxgtk2.8 python-setuptools - > sudo easy_install RunSnakeRun + > sudo apt-get install python-profiler python-wxgtk2.8 python3-pip + > sudo pip install RunSnakeRun See the ``runsnake`` website for instructions for other platforms. diff --git a/src/sage_setup/command/sage_build_cython.py b/src/sage_setup/command/sage_build_cython.py index 2e04bd80f87..6720cd98799 100644 --- a/src/sage_setup/command/sage_build_cython.py +++ b/src/sage_setup/command/sage_build_cython.py @@ -12,8 +12,15 @@ # Import setuptools before importing distutils, so that setuptools # can replace distutils by its own vendored copy. import setuptools - -from distutils import log +import logging + +# Configure logging with simple format showing only level and message +logging.basicConfig( + level=logging.INFO, + format='%(levelname)s: %(message)s', + stream=sys.stdout +) +logger = logging.getLogger(__name__) from setuptools import Command from sage_setup.util import stable_uniq @@ -113,13 +120,13 @@ def finalize_options(self): self.debug = os.environ.get('SAGE_DEBUG', None) != 'no' if self.debug: - log.info('Enabling Cython debugging support') + logger.info('Enabling Cython debugging support') if self.profile is None: self.profile = os.environ.get('SAGE_PROFILE') == 'yes' if self.profile: - log.info('Enabling Cython profiling support') + logger.info('Enabling Cython profiling support') if self.parallel is None: self.parallel = os.environ.get('SAGE_NUM_THREADS', '0') @@ -190,7 +197,7 @@ def get_cythonized_package_files(self): self.cythonized_files = list(find_extra_files( ".", ["sage"], self.build_dir, [], distributions=self.built_distributions).items()) - log.debug(f"cythonized_files = {self.cythonized_files}") + logger.debug(f"cythonized_files = {self.cythonized_files}") return self.cythonized_files @@ -211,7 +218,7 @@ def run(self): Cython.Compiler.Options.embed_pos_in_docstring = True - log.info("Updating Cython code....") + logger.info("Updating Cython code....") t = time.time() from sage.misc.package_dir import cython_namespace_package_support @@ -238,7 +245,7 @@ def run(self): # object is pointed to from different places. self.extensions[:] = extensions - log.info("Finished Cythonizing, time: %.2f seconds." % (time.time() - t)) + logger.info("Finished Cythonizing, time: %.2f seconds." % (time.time() - t)) with open(self._version_file, 'w') as f: f.write(self._version_stamp) diff --git a/src/sage_setup/command/sage_build_ext.py b/src/sage_setup/command/sage_build_ext.py index 5ef452316f0..421a4428880 100644 --- a/src/sage_setup/command/sage_build_ext.py +++ b/src/sage_setup/command/sage_build_ext.py @@ -1,11 +1,20 @@ -import os import errno +import logging +import os +import sys + +# Configure logging with simple format showing only level and message +logging.basicConfig( + level=logging.INFO, + format='%(levelname)s: %(message)s', + stream=sys.stdout +) +logger = logging.getLogger(__name__) # Import setuptools before importing distutils, so that setuptools # can replace distutils by its own vendored copy. import setuptools -from distutils import log from setuptools.command.build_ext import build_ext from distutils.dep_util import newer_group try: @@ -47,7 +56,7 @@ def check_flags(self): flags = ext.extra_compile_args for flag in flags: if forbidden.match(flag): - log.error("%s uses forbidden flag '%s'", ext.name, flag) + logger.error("%s uses forbidden flag '%s'", ext.name, flag) errors += 1 if errors: raise RuntimeError("forbidden flags used") @@ -132,10 +141,10 @@ def prepare_extension(self, ext): 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) + logger.debug("skipping '%s' extension (up-to-date)", ext.name) need_to_compile = False else: - log.info("building '%s' extension", ext.name) + logger.info("building '%s' extension", ext.name) need_to_compile = True return need_to_compile, (sources, ext, ext_filename) diff --git a/src/sage_setup/command/sage_install.py b/src/sage_setup/command/sage_install.py index 052fbecc71e..72605d7468c 100644 --- a/src/sage_setup/command/sage_install.py +++ b/src/sage_setup/command/sage_install.py @@ -2,14 +2,23 @@ ### Install Jupyter kernel spec ######################################################### +import logging import os +import sys import time +# Configure logging with simple format showing only level and message +logging.basicConfig( + level=logging.INFO, + format='%(levelname)s: %(message)s', + stream=sys.stdout +) +logger = logging.getLogger(__name__) + # Import setuptools before importing distutils, so that setuptools # can replace distutils by its own vendored copy. import setuptools -from distutils import log from distutils.command.install import install from setuptools.command.develop import develop diff --git a/src/setup.py b/src/setup.py index 19853e8a228..61e6982e5df 100755 --- a/src/setup.py +++ b/src/setup.py @@ -6,15 +6,23 @@ ## Distribution packaging should use build/pkgs/sagelib/src/setup.py ## instead. +import logging import os import platform import sys import time from setuptools import setup, find_namespace_packages from setuptools.dist import Distribution -from distutils import log import multiprocessing.pool +# Configure logging with simple format showing only level and message +logging.basicConfig( + level=logging.INFO, + format='%(levelname)s: %(message)s', + stream=sys.stdout +) +logger = logging.getLogger(__name__) + # PEP 517 builds do not have . in sys.path sys.path.insert(0, os.path.dirname(__file__)) @@ -70,11 +78,11 @@ extensions = [] python_packages = [] else: - log.info("Generating auto-generated sources") + logger.info("Generating auto-generated sources") from sage_setup.autogen import autogen_all autogen_all() - log.info("Discovering Python/Cython source code...") + logger.info("Discovering Python/Cython source code...") optional_packages = ['mcqd', 'bliss', 'tdlib', 'coxeter3', 'sirocco', 'meataxe'] @@ -82,12 +90,12 @@ for pkg in optional_packages] files_to_exclude = filter_cython_sources(SAGE_SRC, distributions_to_exclude) - log.debug(f"files_to_exclude = {files_to_exclude}") + logger.debug(f"files_to_exclude = {files_to_exclude}") python_packages = find_namespace_packages(where=SAGE_SRC, include=['sage', 'sage.*']) - log.debug(f"python_packages = {python_packages}") + logger.debug(f"python_packages = {python_packages}") - log.info("Discovering Python/Cython source code... done") + logger.info("Discovering Python/Cython source code... done") # from sage_build_cython: import Cython.Compiler.Options @@ -95,11 +103,11 @@ gdb_debug = os.environ.get('SAGE_DEBUG', None) != 'no' aliases = cython_aliases() - log.debug(f"aliases = {aliases}") + logger.debug(f"aliases = {aliases}") include_path = sage_include_directories(use_sources=True) + ['.'] - log.debug(f"include_path = {include_path}") + logger.debug(f"include_path = {include_path}") nthreads = sage_build_ext_minimal.get_default_number_build_jobs() - log.info(f"Cythonizing with {nthreads} threads...") + logger.info(f"Cythonizing with {nthreads} threads...") try: from Cython.Build import cythonize from sage.env import cython_aliases, sage_include_directories @@ -116,9 +124,9 @@ gdb_debug=gdb_debug, nthreads=nthreads) except Exception as exception: - log.warn(f"Exception while cythonizing source files: {repr(exception)}") + logger.warning(f"Exception while cythonizing source files: {repr(exception)}") raise - log.info(f"Cythonizing with {nthreads} threads... done") + logger.info(f"Cythonizing with {nthreads} threads... done") # ######################################################## # ## Distutils diff --git a/tox.ini b/tox.ini index 16f2a706d0a..389fa28a570 100644 --- a/tox.ini +++ b/tox.ini @@ -142,6 +142,7 @@ passenv = EXTRA_SAGE_PACKAGES TARGETS_PRE TARGETS_OPTIONAL + SAGE_EDITABLE docker: EXTRA_DOCKER_BUILD_ARGS docker: EXTRA_DOCKER_TAGS docker: DOCKER_TAG