# scikit-survival on Python 3.14, where the version floors stop agreeing

> A GPL-3.0 survival analysis library built on scikit-learn estimators, still on version 0.28.0 with a Beta classifier and a 2020 paper to cite. Its build requirements relax the scikit-learn pin above Python 3.14 while the installed package keeps a hard cap, and the README states fewer version floors than the manifest does.

**sebp/scikit-survival** — Survival analysis built on top of scikit-learn

- Repository: https://github.com/sebp/scikit-survival
- Stars: 1,323 · Forks: 233
- Language: Python
- License: GPL-3.0
- Published: 2026-09-10 · Updated: 2026-09-10 · Language: en
- Canonical page: https://hysenlabs.com/projects/sebp-scikit-survival

## The scikit-learn cap loosens for Python above 3.14

The build requirements carry two markers for scikit-learn. One pins the compatible release to the 1.9 series for Python up to and including 3.14, and the other applies no version constraint at all for Python above 3.14. The installed package does not follow that leniency, because its runtime dependency is capped at scikit-learn >=1.9.0,<1.10. A build on an interpreter the project has not claimed support for can therefore compile against any scikit-learn release, and the resulting distribution will still refuse to sit beside anything outside the 1.9 line. The classifier list closes the same gap from the other side, naming Python 3.11, 3.12, 3.13 and 3.14 and stopping there. Only one literal install command appears in the Requirements material:

```bash
conda install -c conda-forge scikit-survival
```

Everything else, PyPI and from source, is a link into the hosted documentation rather than a command.

## ecos, clarabel and osqp all arrive for the convex models

Three separate numerical solvers sit in the dependency list. ecos and clarabel cover conic problems, osqp is floored at 1.0.2 or newer for quadratic programs, and numexpr handles the vectorized expressions that would otherwise be written as loops. joblib is there for parallel work. That is a heavier numerical base than a scikit-learn compatible estimator package usually carries, and it is the reason a C/C++ compiler appears in the requirements at all, since the package also declares Cython and C++ classifiers alongside the Python ones. The manifest builds against Cython 3.1.4 or newer, which is stated as being the same requirement scikit-learn uses, and setup.py refuses anything older.

## The README names osqp and scipy bare while the manifest floors both

The Requirements section gives a version for five things: Python 3.11 or later, numpy 2.0.0 or later, pandas 2.2.0 or later, scikit-learn 1.9, and narwhals 2.0.1 or later. The remaining names, clarabel, ecos, joblib, numexpr, osqp and scipy, are listed without one. The manifest is stricter about two of those, flooring osqp at 1.0.2 and scipy at 1.13.0, and the osqp floor is a major version line rather than a loose lower bound. The numpy comment in the build requirements adds a wrinkle: building against numpy 2.x is described as compatible with numpy 1.x, while the runtime requirement asks for numpy 2.0.0 or newer. So the compiler environment and the install environment are not held to the same numpy rule.

## Version 0.28.0, a Beta classifier, and a 2020 paper to cite

The version is not written into the manifest at all. It is declared dynamic and resolved by setuptools-scm from tags, and the recent tags are v0.26.0 on 2025-12-17, v0.27.0 on 2026-02-02 and v0.28.0 on 2026-07-05. The classifier still reads Development Status 4 - Beta, and the cadence has stretched, with five and a half months between the last two tags. The last push to main is 2026-10-01, so the branch is working past v0.28.0 rather than sitting on it. The citation request points at a Journal of Machine Learning Research paper from 2020, volume 21, number 212, with a DOI badge fed from a Zenodo record. A package on its 0.28.0 release and a paper from six years earlier have been on separate numbering schemes the whole time.

## The custom clean command deletes generated C sources

pyproject.toml does most of the work, but setup.py is still present and still runs. It opens with the full GNU General Public License notice, defines CYTHON_MIN_VERSION as 3.1.4, and carries a custom clean command described as adapted from bottleneck's setup.py. What the command does is walk the sksurv directory and collect __pycache__ folders, .pyc and .so files, and any .c or .cpp file that has a matching .pyx beside it, together with the build directory. The rule about .c and .cpp is the interesting one, since a developer editing a .pyx file loses the generated C from the tree on the next clean, which is what stops a stale generated file from shadowing the edit that came after it.

## The docs are published twice, once per branch

Two documentation URLs are offered side by side: the stable path for the latest release and the latest path for the development version built from main. A separate release notes page carries the list of notable changes, and the user guide is presented as in-depth material on the key concepts, an overview of the available survival models, and hands-on examples in Jupyter notebooks form. The repository carries its own documentation source under doc/, a .readthedocs.yaml build configuration, and a .binder directory for running notebooks without a local install. A reader following the development documentation is therefore reading a different build than the one a package index resolves, and the two drift apart between releases.

## narwhals sits beside pandas with no statement about backends

The dependency list contains both pandas 2.2.0 or newer and narwhals 2.0.1 or later, which is two dataframe libraries where one would be enough, and narwhals is floored at a specific patch release rather than a loose lower bound. Nothing in the README or in the manifest says what narwhals is used for, which backends exist, or whether anything other than pandas is tested, so the package metadata alone does not settle whether the estimators are locked to one dataframe library. The requirements list also names a C/C++ compiler as a prerequisite, and the tree carries a .gitmodules file, so part of the test or example setup is fetched from another repository. What those submodules point at is not named in any visible configuration.

## Conclusion

Take the dependency list seriously before installing, because this is a compiled package rather than a pure Python one. From source you need Cython 3.1.4 or newer and a C/C++ compiler, and the manifest also requires Python 3.11 or newer, numpy 2.0.0, pandas 2.2.0 and a compiler that the Requirements section only mentions in passing. The scikit-learn relationship is the part to check against your own environment first: the runtime dependency is capped below 1.10, and the build marker that drops that cap applies to Python versions the classifier list never claims. Anyone who needs a stable API should install a tagged release and read the release notes rather than the development docs, since those two are built from different branches. And anyone planning to use it in a product should read the licensing first: the package metadata records GPL-3.0 and the manifest says GPL-3.0-or-later with license-files pointing at COPYING, which is a different arrangement from the permissive licence of the scikit-learn estimators it wraps.

## FAQ

### how to install scikit survival

The one command given is conda install -c conda-forge scikit-survival, which the README calls the easiest route. PyPI and from-source installation are both linked out to the hosted documentation rather than spelled out, and a source build needs Cython 3.1.4 or newer plus a C/C++ compiler.

### What does scikit-survival need before it will build?

Python 3.11 or later, numpy 2.0.0 or later, pandas 2.2.0 or newer, Cython 3.1.4 or newer, and a C/C++ compiler. The manifest also floors osqp at 1.0.2 and scipy at 1.13.0, two requirements the README's list leaves without a version.

### Which scikit-learn versions work with scikit-survival?

The runtime dependency is capped at scikit-learn >=1.9.0,<1.10. The build requirement pins scikit-learn~=1.9.0 for Python up to 3.14 and drops the version constraint entirely above 3.14, even though the classifier list stops at Python 3.14.

### What license is scikit-survival released under?

The manifest declares GPL-3.0-or-later and sets license-files to COPYING, while the package metadata records GPL-3.0. The classifier set still reads Development Status 4 - Beta, so the project has not moved out of its pre-1.0 numbering.

### How does scikit-survival treat censored training records?

Censoring is treated as the defining property of the data rather than as a gap to fill. A record is uncensored when the exact event time is known, and right censored when a subject stayed event free through the study period and it is unknown whether an event happened later, which is what separates survival analysis from ordinary machine learning.

## Sources

- [Issues](https://github.com/sebp/scikit-survival/issues)
- [License: GPL-3.0](https://github.com/sebp/scikit-survival/blob/main/LICENSE)
- [README](https://github.com/sebp/scikit-survival/blob/main/README.md)
- [Releases](https://github.com/sebp/scikit-survival/releases)
- [sebp/scikit-survival on GitHub](https://github.com/sebp/scikit-survival)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/sebp-scikit-survival
