Skip to content

DEV: Build System and Packaging Update#138

Merged
broesler merged 30 commits into
scikit-sparse:masterfrom
broesler:build-system
Feb 11, 2026
Merged

DEV: Build System and Packaging Update#138
broesler merged 30 commits into
scikit-sparse:masterfrom
broesler:build-system

Conversation

@broesler
Copy link
Copy Markdown
Collaborator

@broesler broesler commented Jul 30, 2025

Build System Update

This PR updates the build system to use PEP 621
and store project metadata in pyproject.toml instead of setup.py.

Changes include:

  • Update to PEP 621 project metadata in pyproject.toml
  • Remove support for Python 3.9 and earlier, and Numpy < v2.0.
  • Update installation logic in setup.py to improve reliability
  • Update test logic to remove pkg_resources dependency and redundant test
    directory
  • Update documentation to reflect changes and add intersphinx links
  • Add GitHub Actions workflow for testing the build system and development code

Description

The project metadata and packaging have not been updated for many years.
The goal of this PR is to modernize the build system and prepare for future
enhancements, such as adding more SuiteSparse module interfaces. It does not
change the existing API or functionality of scikit-sparse. This PR
updates the packaging and installation to have a unified source of metadata in
pyproject.toml, in preparation for the addition of more SuiteSparse module
interfaces like AMD, COLAMD, etc.

The pyproject.toml file now contains all necessary metadata, including project
name, version, description, authors, license, dependencies, and build system
requirements.

Version Bump

The major breaking change is the removal of support for Python 3.9 and earlier,
as well as Numpy < v2.0. As noted in changes.rst, Python 3.9 will reach its
end of life in October 2025. Numpy will end support for all v1.x versions by
September 2025. SciPy v1.14 (released June 2024) will be supported until the end
of 2026. This change ensures that scikit-sparse remains compatible with the
latest versions of Python and Numpy, without creating undue burden on us as
maintainers to stay compatible with older versions.

I have bumped the version to 0.5.0 to reflect these changes. The version
is now solely managed in pyproject.toml. sksparse/__init__.py has been
updated to read the version from pyproject.toml instead of hardcoding it.

Installation Changes

There is no user-visible change to the installation process, but the underlying
logic has been updated to improve reliability and flexibility.

The installation logic remains in setup.py, but is now restructured to ensure
user setting of SUITESPARSE_INCLUDE_DIR and SUITESPARSE_LIBRARY_DIR
overrides any other installation location. Previously, these environment
variables were placed at the end of the include list, leading to potential
issues when users had multiple installation locations for SuiteSparse.

setup.py will now automatically detect the SuiteSparse library and compile the
necessary Cython code. It will check for the SuiteSparse library in the
following order:

  1. The environment variables SUITESPARSE_INCLUDE_DIR and
    SUITESPARSE_LIB_DIR (if set, these will override the default search
    paths)
  2. Your active conda environment path
  3. Your homebrew paths (e.g. /opt/homebrew/include/suitesparse)
  4. Typical system paths (e.g. /usr/include/suitesparse on Linux, or
    /usr/local/include/suitesparse on macOS)

This information is reflected in changes to the README.md and overview.rst
files.

Test Changes

There is one minor change to test_cholmod.py. The mm_matrix function
previously used pkg_resources to load a matrix from a file, requiring the test
data to be copied into the package directory. Since pkg_resources is outdated
and not recommended for new code, the function now directly uses the path of the
test file, which is more straightforward and avoids the need for copying test
data into the package directory. This PR removes the redundant sksparse/tests
directory. All test files are now located in tests/.

Documentation Changes

Copyright information has been updated to reflect the new year and contributors.
Existing files retain the full license information and author list, but new
files should only include the copyright notice and a reference to the full
license information in LICENSE.txt, as well as the author list in
pyproject.toml.

Switch to Ruff from Black

Both the numpy and scipy projects use ruff for linting and formatting instead of black. This PR updates pyproject.toml with... roughly the same ruff settings as used in those projects. The CI workflow currently does not run linting/formatting, because there are a number of changes that would be made to existing code to update to at least Python v3.10. I will submit a separate PR with these style updates.

CI Workflows

This PR reorganizes the GitHub Actions workflows into 3 parts:

  1. former ci_test.yml -> deploy.yml
  2. ci-dev.yml: Install the development version, run pytest and build the docs.
  3. build-test.yml: Build the distribution wheel and sdist, check both for file contents, and install/test.

The deploy.yml file has minor updates to reflect the changes to the build system, but is otherwise unchanged.
ci-dev.yml is trigged on pull requests, or manually. Contributors can change this to run on pushes to their local fork feature branches, as necessary. build-test.yml is triggered on pushes to the build-system branch, or manually.

Additional Comments

I have another PR in the works that will add an interface for AMD, and plans to
include COLAMD, CAMD, and CCOLAMD interfaces in the near future.

Looking forward to your feedback and suggestions on this PR!

broesler added 10 commits July 28, 2025 20:35
The setup.py file now includes possible SuiteSparse installation
directories in this order:
1. user-defined SUITESPARSE_INCLUDE_DIR/SUITESPARSE_LIBRARY_DIR
2. user's active conda environment path
3. user's homebrew path
4. default system installation paths (MacOS and Debian)
The ruff settings are chosen to closely match those of the numpy and
scipy projects.

This commit also removes unnecessary excludes from the black settings,
because ruff excludes those directories/files by default.
Also refer to pyproject.toml for complete author list where appropriate,
and add existing authors to overview.rst.

Future files should not include the license and full author list, since
those are included in LICENSE.txt and pyproject.toml, respectively, but
legacy files will retain that information.
Exclude source files *.pyx and *.c from the wheel file since they are
not runtime dependencies (see pyproject.toml). Include them in the sdist
(via MANIFEST.in) so that users can build from source if desired. Also
include test files in the sdist.
Use conda to install into a clean environment in CI and check that
sksparse installs correctly.
This commit makes the CI workflows much cleaner. There is now:

1. ci-dev.yml: a workflow that can be run on development branches to
  test code changes,
2. build-check.yml: a workflow that can be run on the
   "build-system" branch to test changes to the build system,
3. deploy.yml: a workflow that can be run on releases.
This commit ensures "ruff check" is run on any files to be committed, so
that we don't end up with linting errors in CI, or a bunch of tiny
commits fixing style errors. It does *not* run "ruff check --fix" or
"ruff format", so no files will be changed unless done so explicitly by
the developer. Also adds "pre-commit" as a dev dependency.
@AaronDJohnson AaronDJohnson self-requested a review November 23, 2025 00:49
@broesler broesler mentioned this pull request Dec 12, 2025
@broesler broesler merged commit 5b58422 into scikit-sparse:master Feb 11, 2026
@broesler broesler deleted the build-system branch February 11, 2026 20:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant