survival 0.0.6__tar.gz → 1.1.16__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of survival might be problematic. Click here for more details.

Files changed (295) hide show
  1. survival-1.1.16/.cargo/config.toml +6 -0
  2. survival-1.1.16/.github/dependabot.yml +16 -0
  3. survival-1.1.16/.github/workflows/lint.yml +103 -0
  4. survival-1.1.16/.github/workflows/publish.yml +234 -0
  5. survival-1.1.16/.github/workflows/release.yml +45 -0
  6. survival-1.1.16/.github/workflows/rust.yml +185 -0
  7. survival-1.1.16/.github/workflows/security.yml +38 -0
  8. survival-1.1.16/.github/workflows/version-bump.yml +43 -0
  9. survival-1.1.16/.gitignore +25 -0
  10. survival-1.1.16/.pre-commit-config.yaml +52 -0
  11. survival-1.1.16/.typos.toml +12 -0
  12. survival-1.1.16/Cargo.lock +1559 -0
  13. survival-1.1.16/Cargo.toml +52 -0
  14. survival-1.1.16/LICENSE +21 -0
  15. survival-1.1.16/PKG-INFO +675 -0
  16. survival-1.1.16/README.md +638 -0
  17. survival-1.1.16/SECURITY.md +19 -0
  18. survival-1.1.16/pyproject.toml +69 -0
  19. survival-1.1.16/ruff.toml +28 -0
  20. survival-1.1.16/src/agexact.pyx +68 -0
  21. survival-1.1.16/src/bayesian/bayesian_cox.rs +634 -0
  22. survival-1.1.16/src/bayesian/bayesian_parametric.rs +572 -0
  23. survival-1.1.16/src/bayesian/mod.rs +2 -0
  24. survival-1.1.16/src/causal/g_computation.rs +401 -0
  25. survival-1.1.16/src/causal/ipcw.rs +380 -0
  26. survival-1.1.16/src/causal/mod.rs +4 -0
  27. survival-1.1.16/src/causal/msm.rs +429 -0
  28. survival-1.1.16/src/causal/target_trial.rs +592 -0
  29. survival-1.1.16/src/chinv2.pyx +29 -0
  30. survival-1.1.16/src/cholesky2.pyx +42 -0
  31. survival-1.1.16/src/chsolve2.pyx +23 -0
  32. survival-1.1.16/src/concordance/basic.rs +129 -0
  33. survival-1.1.16/src/concordance/common.rs +118 -0
  34. survival-1.1.16/src/concordance/concordance1.rs +185 -0
  35. survival-1.1.16/src/concordance/concordance3.rs +156 -0
  36. survival-1.1.16/src/concordance/concordance5.rs +167 -0
  37. survival-1.1.16/src/concordance/mod.rs +5 -0
  38. survival-1.1.16/src/constants.rs +35 -0
  39. survival-1.1.16/src/core/coxcount1.rs +224 -0
  40. survival-1.1.16/src/core/coxscho.rs +155 -0
  41. survival-1.1.16/src/core/mod.rs +4 -0
  42. survival-1.1.16/src/core/nsk.rs +328 -0
  43. survival-1.1.16/src/core/pspline.rs +456 -0
  44. survival-1.1.16/src/datasets/data/aml.csv +24 -0
  45. survival-1.1.16/src/datasets/data/bladder.csv +341 -0
  46. survival-1.1.16/src/datasets/data/cgd.csv +204 -0
  47. survival-1.1.16/src/datasets/data/cgd0.csv +129 -0
  48. survival-1.1.16/src/datasets/data/colon.csv +1859 -0
  49. survival-1.1.16/src/datasets/data/diabetic.csv +395 -0
  50. survival-1.1.16/src/datasets/data/flchain.csv +7875 -0
  51. survival-1.1.16/src/datasets/data/gbsg.csv +687 -0
  52. survival-1.1.16/src/datasets/data/heart.csv +173 -0
  53. survival-1.1.16/src/datasets/data/hoel.csv +44 -0
  54. survival-1.1.16/src/datasets/data/kidney.csv +77 -0
  55. survival-1.1.16/src/datasets/data/logan.csv +839 -0
  56. survival-1.1.16/src/datasets/data/lung.csv +229 -0
  57. survival-1.1.16/src/datasets/data/mgus.csv +242 -0
  58. survival-1.1.16/src/datasets/data/mgus2.csv +1385 -0
  59. survival-1.1.16/src/datasets/data/myeloid.csv +647 -0
  60. survival-1.1.16/src/datasets/data/myeloma.csv +62 -0
  61. survival-1.1.16/src/datasets/data/nafld.csv +17550 -0
  62. survival-1.1.16/src/datasets/data/nwtco.csv +4029 -0
  63. survival-1.1.16/src/datasets/data/ovarian.csv +27 -0
  64. survival-1.1.16/src/datasets/data/pbc.csv +419 -0
  65. survival-1.1.16/src/datasets/data/pbcseq.csv +1946 -0
  66. survival-1.1.16/src/datasets/data/rats.csv +33 -0
  67. survival-1.1.16/src/datasets/data/rats2.csv +254 -0
  68. survival-1.1.16/src/datasets/data/retinopathy.csv +395 -0
  69. survival-1.1.16/src/datasets/data/rhDNase.csv +41 -0
  70. survival-1.1.16/src/datasets/data/rotterdam.csv +2983 -0
  71. survival-1.1.16/src/datasets/data/solder.csv +901 -0
  72. survival-1.1.16/src/datasets/data/stanford2.csv +185 -0
  73. survival-1.1.16/src/datasets/data/tobin.csv +21 -0
  74. survival-1.1.16/src/datasets/data/transplant.csv +816 -0
  75. survival-1.1.16/src/datasets/data/udca.csv +171 -0
  76. survival-1.1.16/src/datasets/data/veteran.csv +138 -0
  77. survival-1.1.16/src/datasets/mod.rs +958 -0
  78. survival-1.1.16/src/datasets/parser.rs +120 -0
  79. survival-1.1.16/src/doloop.pyx +40 -0
  80. survival-1.1.16/src/interval/interval_censoring.rs +552 -0
  81. survival-1.1.16/src/interval/mod.rs +1 -0
  82. survival-1.1.16/src/joint/dynamic_prediction.rs +519 -0
  83. survival-1.1.16/src/joint/joint_model.rs +673 -0
  84. survival-1.1.16/src/joint/mod.rs +2 -0
  85. survival-1.1.16/src/lib.rs +609 -0
  86. survival-1.1.16/src/matrix/chinv2.rs +42 -0
  87. survival-1.1.16/src/matrix/cholesky2.rs +48 -0
  88. survival-1.1.16/src/matrix/mod.rs +2 -0
  89. survival-1.1.16/src/missing/mod.rs +2 -0
  90. survival-1.1.16/src/missing/multiple_imputation.rs +757 -0
  91. survival-1.1.16/src/missing/pattern_mixture.rs +614 -0
  92. survival-1.1.16/src/ml/gradient_boost.rs +717 -0
  93. survival-1.1.16/src/ml/mod.rs +2 -0
  94. survival-1.1.16/src/ml/survival_forest.rs +825 -0
  95. survival-1.1.16/src/pybridge/cox_py_callback.rs +60 -0
  96. survival-1.1.16/src/pybridge/mod.rs +14 -0
  97. survival-1.1.16/src/pybridge/pyears3b.rs +349 -0
  98. survival-1.1.16/src/pybridge/pystep.rs +218 -0
  99. survival-1.1.16/src/qol/mod.rs +2 -0
  100. survival-1.1.16/src/qol/qaly.rs +387 -0
  101. survival-1.1.16/src/qol/qtwist.rs +311 -0
  102. survival-1.1.16/src/recurrent/gap_time.rs +382 -0
  103. survival-1.1.16/src/recurrent/joint_frailty.rs +361 -0
  104. survival-1.1.16/src/recurrent/marginal_models.rs +437 -0
  105. survival-1.1.16/src/recurrent/mod.rs +3 -0
  106. survival-1.1.16/src/regression/aareg.rs +477 -0
  107. survival-1.1.16/src/regression/agfit5.rs +409 -0
  108. survival-1.1.16/src/regression/blogit.rs +50 -0
  109. survival-1.1.16/src/regression/clogit.rs +132 -0
  110. survival-1.1.16/src/regression/coxfit6.rs +714 -0
  111. survival-1.1.16/src/regression/coxph.rs +814 -0
  112. survival-1.1.16/src/regression/coxph_detail.rs +279 -0
  113. survival-1.1.16/src/regression/cure_models.rs +660 -0
  114. survival-1.1.16/src/regression/elastic_net.rs +686 -0
  115. survival-1.1.16/src/regression/mod.rs +13 -0
  116. survival-1.1.16/src/regression/ridge.rs +463 -0
  117. survival-1.1.16/src/regression/survreg6.rs +651 -0
  118. survival-1.1.16/src/regression/survreg_predict.rs +338 -0
  119. survival-1.1.16/src/regression/survregc1.rs +499 -0
  120. survival-1.1.16/src/relative/mod.rs +2 -0
  121. survival-1.1.16/src/relative/net_survival.rs +465 -0
  122. survival-1.1.16/src/relative/relative_survival.rs +421 -0
  123. survival-1.1.16/src/residuals/agmart.rs +112 -0
  124. survival-1.1.16/src/residuals/coxmart.rs +137 -0
  125. survival-1.1.16/src/residuals/mod.rs +4 -0
  126. survival-1.1.16/src/residuals/survfit_resid.rs +249 -0
  127. survival-1.1.16/src/residuals/survreg_resid.rs +381 -0
  128. survival-1.1.16/src/scoring/agscore2.rs +161 -0
  129. survival-1.1.16/src/scoring/agscore3.rs +221 -0
  130. survival-1.1.16/src/scoring/common.rs +151 -0
  131. survival-1.1.16/src/scoring/coxscore2.rs +325 -0
  132. survival-1.1.16/src/scoring/mod.rs +4 -0
  133. survival-1.1.16/src/spatial/mod.rs +1 -0
  134. survival-1.1.16/src/spatial/spatial_frailty.rs +710 -0
  135. survival-1.1.16/src/specialized/brier.rs +144 -0
  136. survival-1.1.16/src/specialized/cch.rs +46 -0
  137. survival-1.1.16/src/specialized/cipoisson.rs +51 -0
  138. survival-1.1.16/src/specialized/finegray.rs +119 -0
  139. survival-1.1.16/src/specialized/mod.rs +10 -0
  140. survival-1.1.16/src/specialized/norisk.rs +57 -0
  141. survival-1.1.16/src/specialized/pyears_summary.rs +242 -0
  142. survival-1.1.16/src/specialized/ratetable.rs +496 -0
  143. survival-1.1.16/src/specialized/statefig.rs +310 -0
  144. survival-1.1.16/src/specialized/survexp.rs +370 -0
  145. survival-1.1.16/src/specialized/survexp_us.rs +248 -0
  146. survival-1.1.16/src/surv_analysis/aggregate_survfit.rs +241 -0
  147. survival-1.1.16/src/surv_analysis/agsurv4.rs +49 -0
  148. survival-1.1.16/src/surv_analysis/agsurv5.rs +54 -0
  149. survival-1.1.16/src/surv_analysis/mod.rs +9 -0
  150. survival-1.1.16/src/surv_analysis/nelson_aalen.rs +420 -0
  151. survival-1.1.16/src/surv_analysis/pseudo.rs +307 -0
  152. survival-1.1.16/src/surv_analysis/survdiff2.rs +227 -0
  153. survival-1.1.16/src/surv_analysis/survfit_matrix.rs +407 -0
  154. survival-1.1.16/src/surv_analysis/survfitaj.rs +418 -0
  155. survival-1.1.16/src/surv_analysis/survfitkm.rs +453 -0
  156. survival-1.1.16/src/tests/common.rs +118 -0
  157. survival-1.1.16/src/tests/mod.rs +6 -0
  158. survival-1.1.16/src/tests/r_exact_validation.rs +696 -0
  159. survival-1.1.16/src/tests/r_survival_validation.rs +1171 -0
  160. survival-1.1.16/src/tests/r_validation_tests.rs +420 -0
  161. survival-1.1.16/src/tests/unit_tests.rs +357 -0
  162. survival-1.1.16/src/tests/validation_tests.rs +377 -0
  163. survival-1.1.16/src/utilities/aeq_surv.rs +123 -0
  164. survival-1.1.16/src/utilities/agexact.rs +577 -0
  165. survival-1.1.16/src/utilities/cluster.rs +153 -0
  166. survival-1.1.16/src/utilities/collapse.rs +63 -0
  167. survival-1.1.16/src/utilities/fenwick.rs +60 -0
  168. survival-1.1.16/src/utilities/matrix.rs +190 -0
  169. survival-1.1.16/src/utilities/mod.rs +19 -0
  170. survival-1.1.16/src/utilities/neardate.rs +276 -0
  171. survival-1.1.16/src/utilities/numpy_utils.rs +92 -0
  172. survival-1.1.16/src/utilities/reliability.rs +431 -0
  173. survival-1.1.16/src/utilities/rttright.rs +259 -0
  174. survival-1.1.16/src/utilities/statistical.rs +275 -0
  175. survival-1.1.16/src/utilities/strata.rs +135 -0
  176. survival-1.1.16/src/utilities/surv2data.rs +187 -0
  177. survival-1.1.16/src/utilities/survcondense.rs +189 -0
  178. survival-1.1.16/src/utilities/survsplit.rs +82 -0
  179. survival-1.1.16/src/utilities/tcut.rs +260 -0
  180. survival-1.1.16/src/utilities/timeline.rs +238 -0
  181. survival-1.1.16/src/utilities/tmerge.rs +86 -0
  182. survival-1.1.16/src/utilities/validation.rs +167 -0
  183. survival-1.1.16/src/validation/anova.rs +225 -0
  184. survival-1.1.16/src/validation/bootstrap.rs +417 -0
  185. survival-1.1.16/src/validation/calibration.rs +576 -0
  186. survival-1.1.16/src/validation/crossval.rs +385 -0
  187. survival-1.1.16/src/validation/landmark.rs +835 -0
  188. survival-1.1.16/src/validation/logrank.rs +367 -0
  189. survival-1.1.16/src/validation/mod.rs +14 -0
  190. survival-1.1.16/src/validation/power.rs +291 -0
  191. survival-1.1.16/src/validation/rmst.rs +900 -0
  192. survival-1.1.16/src/validation/royston.rs +249 -0
  193. survival-1.1.16/src/validation/survcheck.rs +338 -0
  194. survival-1.1.16/src/validation/survobrien.rs +280 -0
  195. survival-1.1.16/src/validation/tests.rs +262 -0
  196. survival-1.1.16/src/validation/uno_c_index.rs +586 -0
  197. survival-1.1.16/src/validation/yates.rs +399 -0
  198. survival-1.1.16/survival.pyi +963 -0
  199. survival-1.1.16/test/README.md +78 -0
  200. survival-1.1.16/test/aareg.rs +95 -0
  201. survival-1.1.16/test/anova.rs +59 -0
  202. survival-1.1.16/test/bladder.rs +80 -0
  203. survival-1.1.16/test/book1.rs +99 -0
  204. survival-1.1.16/test/book2.rs +155 -0
  205. survival-1.1.16/test/book3.rs +180 -0
  206. survival-1.1.16/test/book4.rs +224 -0
  207. survival-1.1.16/test/book5.rs +138 -0
  208. survival-1.1.16/test/book6.rs +131 -0
  209. survival-1.1.16/test/book7.rs +70 -0
  210. survival-1.1.16/test/brier.rs +111 -0
  211. survival-1.1.16/test/cancer.rs +102 -0
  212. survival-1.1.16/test/checksurv2.rs +155 -0
  213. survival-1.1.16/test/clogit.rs +64 -0
  214. survival-1.1.16/test/concordance.rs +157 -0
  215. survival-1.1.16/test/concordance1.py +46 -0
  216. survival-1.1.16/test/concordance2.rs +209 -0
  217. survival-1.1.16/test/concordance3.rs +136 -0
  218. survival-1.1.16/test/coxsurv.rs +73 -0
  219. survival-1.1.16/test/coxsurv2.rs +72 -0
  220. survival-1.1.16/test/coxsurv3.rs +99 -0
  221. survival-1.1.16/test/coxsurv4.rs +173 -0
  222. survival-1.1.16/test/coxsurv5.rs +318 -0
  223. survival-1.1.16/test/coxsurv6.rs +88 -0
  224. survival-1.1.16/test/detail.rs +128 -0
  225. survival-1.1.16/test/difftest.rs +105 -0
  226. survival-1.1.16/test/doaml.rs +315 -0
  227. survival-1.1.16/test/doublecolon.rs +23 -0
  228. survival-1.1.16/test/doweight.rs +85 -0
  229. survival-1.1.16/test/dropspecial.rs +151 -0
  230. survival-1.1.16/test/ekm.rs +179 -0
  231. survival-1.1.16/test/expected.rs +173 -0
  232. survival-1.1.16/test/expected2.rs +93 -0
  233. survival-1.1.16/test/factor.rs +124 -0
  234. survival-1.1.16/test/factor2.rs +90 -0
  235. survival-1.1.16/test/finegray.rs +146 -0
  236. survival-1.1.16/test/generate_r_expected_values.R +372 -0
  237. survival-1.1.16/test/helpers.py +69 -0
  238. survival-1.1.16/test/mstate.rs +268 -0
  239. survival-1.1.16/test/mstate2.rs +71 -0
  240. survival-1.1.16/test/mstrata.rs +26 -0
  241. survival-1.1.16/test/multi2.rs +78 -0
  242. survival-1.1.16/test/multi3.rs +71 -0
  243. survival-1.1.16/test/multistate.rs +80 -0
  244. survival-1.1.16/test/neardate.rs +126 -0
  245. survival-1.1.16/test/nested.rs +84 -0
  246. survival-1.1.16/test/nsk.rs +109 -0
  247. survival-1.1.16/test/ovarian.rs +73 -0
  248. survival-1.1.16/test/r_expected_values.json +198 -0
  249. survival-1.1.16/test/run_tests.sh +15 -0
  250. survival-1.1.16/test/test_all.py +64 -0
  251. survival-1.1.16/test/test_array_inputs.py +189 -0
  252. survival-1.1.16/test/test_classes.py +119 -0
  253. survival-1.1.16/test/test_concordance_additional.py +79 -0
  254. survival-1.1.16/test/test_core.py +54 -0
  255. survival-1.1.16/test/test_dataframe_integration.py +164 -0
  256. survival-1.1.16/test/test_edge_cases.py +126 -0
  257. survival-1.1.16/test/test_regression.py +154 -0
  258. survival-1.1.16/test/test_specialized.py +86 -0
  259. survival-1.1.16/test/test_surv_analysis.py +114 -0
  260. survival-1.1.16/test/test_utilities.py +40 -0
  261. survival-1.1.16/uv.lock +8 -0
  262. survival-0.0.6/PKG-INFO +0 -194
  263. survival-0.0.6/README.md +0 -184
  264. survival-0.0.6/distributions/__init__.py +0 -0
  265. survival-0.0.6/distributions/basemodel.py +0 -336
  266. survival-0.0.6/distributions/exponential.py +0 -71
  267. survival-0.0.6/distributions/loglogistic.py +0 -389
  268. survival-0.0.6/distributions/lognormal.py +0 -91
  269. survival-0.0.6/distributions/lomax.py +0 -364
  270. survival-0.0.6/distributions/mixture/__init__.py +0 -0
  271. survival-0.0.6/distributions/mixture/basemixture.py +0 -27
  272. survival-0.0.6/distributions/mixture/exponmix.py +0 -32
  273. survival-0.0.6/distributions/mixture/exponmix_censored.py +0 -164
  274. survival-0.0.6/distributions/mixture/gaussianmix.py +0 -121
  275. survival-0.0.6/distributions/mixture/genericmix.py +0 -30
  276. survival-0.0.6/distributions/regressed/__init__.py +0 -0
  277. survival-0.0.6/distributions/regressed/basemodelregressed.py +0 -193
  278. survival-0.0.6/distributions/regressed/loglogisticregr.py +0 -18
  279. survival-0.0.6/distributions/weibull.py +0 -461
  280. survival-0.0.6/markovchains/__init__.py +0 -0
  281. survival-0.0.6/markovchains/markovchains.py +0 -193
  282. survival-0.0.6/misc/__init__.py +0 -0
  283. survival-0.0.6/misc/misc.py +0 -38
  284. survival-0.0.6/misc/sigmoid.py +0 -22
  285. survival-0.0.6/nonparametric/__init__.py +0 -0
  286. survival-0.0.6/nonparametric/non_parametric.py +0 -116
  287. survival-0.0.6/optimization/__init__.py +0 -0
  288. survival-0.0.6/optimization/optimizn.py +0 -30
  289. survival-0.0.6/setup.cfg +0 -4
  290. survival-0.0.6/setup.py +0 -13
  291. survival-0.0.6/survival.egg-info/PKG-INFO +0 -194
  292. survival-0.0.6/survival.egg-info/SOURCES.txt +0 -32
  293. survival-0.0.6/survival.egg-info/dependency_links.txt +0 -1
  294. survival-0.0.6/survival.egg-info/not-zip-safe +0 -1
  295. survival-0.0.6/survival.egg-info/top_level.txt +0 -5
@@ -0,0 +1,6 @@
1
+ [build]
2
+ rustflags = ["-Dwarnings"]
3
+
4
+ # For builds with AVX2
5
+ # [target.x86_64-unknown-linux-gnu]
6
+ # rustflags = ["-C", "target-feature=+avx2,+fma", "-Dwarnings"]
@@ -0,0 +1,16 @@
1
+ version: 2
2
+ updates:
3
+ - package-ecosystem: "cargo"
4
+ directory: "/"
5
+ schedule:
6
+ interval: "weekly"
7
+
8
+ - package-ecosystem: "pip"
9
+ directory: "/"
10
+ schedule:
11
+ interval: "weekly"
12
+
13
+ - package-ecosystem: "github-actions"
14
+ directory: "/"
15
+ schedule:
16
+ interval: "weekly"
@@ -0,0 +1,103 @@
1
+ name: Lint
2
+
3
+ on:
4
+ pull_request:
5
+ branches: [main]
6
+
7
+ env:
8
+ CARGO_TERM_COLOR: always
9
+
10
+ jobs:
11
+ rust-lint:
12
+ name: Rust Lint & Format
13
+ runs-on: ubuntu-latest
14
+ steps:
15
+ - name: Checkout code
16
+ uses: actions/checkout@v6
17
+
18
+ - name: Install Rust
19
+ uses: dtolnay/rust-toolchain@stable
20
+ with:
21
+ components: rustfmt, clippy
22
+
23
+ - name: Cache Rust dependencies
24
+ uses: actions/cache@v5
25
+ with:
26
+ path: |
27
+ ~/.cargo/bin/
28
+ ~/.cargo/registry/index/
29
+ ~/.cargo/registry/cache/
30
+ ~/.cargo/git/db/
31
+ target/
32
+ key: ${{ runner.os }}-cargo-lint-${{ hashFiles('**/Cargo.lock') }}
33
+ restore-keys: |
34
+ ${{ runner.os }}-cargo-
35
+
36
+ - name: Check formatting
37
+ run: cargo fmt --all -- --check
38
+
39
+ - name: Run clippy
40
+ run: cargo clippy --all-targets --all-features -- -D warnings
41
+
42
+ - name: Check for unused dependencies
43
+ run: |
44
+ cargo install cargo-machete || true
45
+ cargo machete || true
46
+
47
+ python-lint:
48
+ name: Python Lint & Format
49
+ runs-on: ubuntu-latest
50
+ steps:
51
+ - name: Checkout code
52
+ uses: actions/checkout@v6
53
+
54
+ - name: Set up Python
55
+ uses: actions/setup-python@v6
56
+ with:
57
+ python-version: '3.14'
58
+
59
+ - name: Install uv
60
+ uses: astral-sh/setup-uv@v7
61
+
62
+ - name: Install linters
63
+ run: uv pip install --system ruff mypy
64
+
65
+ - name: Check formatting
66
+ run: ruff format test/ --check
67
+
68
+ - name: Lint code
69
+ run: ruff check test/
70
+
71
+ - name: Type check stubs
72
+ run: |
73
+ uv pip install --system numpy
74
+ mypy survival.pyi --ignore-missing-imports || true
75
+
76
+ typos:
77
+ name: Spell Check
78
+ runs-on: ubuntu-latest
79
+ steps:
80
+ - name: Checkout code
81
+ uses: actions/checkout@v6
82
+
83
+ - name: Check for typos
84
+ uses: crate-ci/typos@master
85
+ with:
86
+ config: .typos.toml
87
+ continue-on-error: true
88
+
89
+ veto:
90
+ name: Veto
91
+ runs-on: ubuntu-latest
92
+ needs: [rust-lint, python-lint, typos]
93
+ if: always()
94
+ steps:
95
+ - name: Check all lint jobs passed
96
+ run: |
97
+ if [[ "${{ needs.rust-lint.result }}" != "success" ]] || \
98
+ [[ "${{ needs.python-lint.result }}" != "success" ]] || \
99
+ [[ "${{ needs.typos.result }}" != "success" ]]; then
100
+ echo "One or more lint jobs failed"
101
+ exit 1
102
+ fi
103
+ echo "All lint jobs passed"
@@ -0,0 +1,234 @@
1
+ name: Publish
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ release:
7
+ types: [published]
8
+ workflow_dispatch:
9
+ inputs:
10
+ target:
11
+ description: 'Publish target'
12
+ required: true
13
+ default: 'testpypi'
14
+ type: choice
15
+ options:
16
+ - testpypi
17
+ - pypi
18
+
19
+ permissions:
20
+ contents: write
21
+
22
+ env:
23
+ CARGO_TERM_COLOR: always
24
+
25
+ jobs:
26
+ linux-x86:
27
+ runs-on: ubuntu-latest
28
+ steps:
29
+ - uses: actions/checkout@v6
30
+ with:
31
+ ref: ${{ github.event_name == 'push' && 'main' || github.ref }}
32
+
33
+ - uses: actions/setup-python@v6
34
+ with:
35
+ python-version: '3.14'
36
+
37
+ - name: Build wheels
38
+ uses: PyO3/maturin-action@v1
39
+ with:
40
+ args: --release --out dist
41
+
42
+ - name: Upload wheels
43
+ uses: actions/upload-artifact@v6
44
+ with:
45
+ name: wheels-linux-x86_64
46
+ path: dist
47
+
48
+ linux-arm:
49
+ runs-on: ubuntu-24.04-arm
50
+ steps:
51
+ - uses: actions/checkout@v6
52
+ with:
53
+ ref: ${{ github.event_name == 'push' && 'main' || github.ref }}
54
+
55
+ - uses: actions/setup-python@v6
56
+ with:
57
+ python-version: '3.14'
58
+
59
+ - name: Build wheels
60
+ uses: PyO3/maturin-action@v1
61
+ with:
62
+ args: --release --out dist
63
+
64
+ - name: Upload wheels
65
+ uses: actions/upload-artifact@v6
66
+ with:
67
+ name: wheels-linux-aarch64
68
+ path: dist
69
+
70
+ macos:
71
+ runs-on: macos-14
72
+ strategy:
73
+ matrix:
74
+ target: [x86_64-apple-darwin, aarch64-apple-darwin]
75
+ steps:
76
+ - uses: actions/checkout@v6
77
+ with:
78
+ ref: ${{ github.event_name == 'push' && 'main' || github.ref }}
79
+
80
+ - uses: actions/setup-python@v6
81
+ with:
82
+ python-version: '3.14'
83
+
84
+ - name: Build wheels
85
+ uses: PyO3/maturin-action@v1
86
+ with:
87
+ target: ${{ matrix.target }}
88
+ args: --release --out dist
89
+
90
+ - name: Upload wheels
91
+ uses: actions/upload-artifact@v6
92
+ with:
93
+ name: wheels-macos-${{ matrix.target }}
94
+ path: dist
95
+
96
+ windows:
97
+ runs-on: windows-latest
98
+ steps:
99
+ - uses: actions/checkout@v6
100
+ with:
101
+ ref: ${{ github.event_name == 'push' && 'main' || github.ref }}
102
+
103
+ - uses: actions/setup-python@v6
104
+ with:
105
+ python-version: '3.14'
106
+
107
+ - name: Build wheels
108
+ uses: PyO3/maturin-action@v1
109
+ with:
110
+ target: x86_64-pc-windows-msvc
111
+ args: --release --out dist
112
+
113
+ - name: Upload wheels
114
+ uses: actions/upload-artifact@v6
115
+ with:
116
+ name: wheels-windows-x64
117
+ path: dist
118
+
119
+ sdist:
120
+ runs-on: ubuntu-latest
121
+ steps:
122
+ - uses: actions/checkout@v6
123
+ with:
124
+ ref: ${{ github.event_name == 'push' && 'main' || github.ref }}
125
+
126
+ - name: Build sdist
127
+ uses: PyO3/maturin-action@v1
128
+ with:
129
+ command: sdist
130
+ args: --out dist
131
+
132
+ - name: Upload sdist
133
+ uses: actions/upload-artifact@v6
134
+ with:
135
+ name: wheels-sdist
136
+ path: dist
137
+
138
+ publish-testpypi:
139
+ name: Publish to TestPyPI
140
+ runs-on: ubuntu-latest
141
+ if: github.event_name == 'workflow_dispatch' && github.event.inputs.target == 'testpypi'
142
+ needs: [linux-x86, linux-arm, macos, windows, sdist]
143
+ environment:
144
+ name: testpypi
145
+ url: https://test.pypi.org/project/survival
146
+ permissions:
147
+ id-token: write
148
+ steps:
149
+ - uses: actions/download-artifact@v7
150
+ with:
151
+ path: dist
152
+ merge-multiple: true
153
+
154
+ - name: Publish to TestPyPI
155
+ uses: pypa/gh-action-pypi-publish@release/v1
156
+ with:
157
+ repository-url: https://test.pypi.org/legacy/
158
+
159
+ publish-pypi:
160
+ name: Publish to PyPI
161
+ runs-on: ubuntu-latest
162
+ if: github.event_name == 'push' || github.event_name == 'release' || (github.event_name == 'workflow_dispatch' && github.event.inputs.target == 'pypi')
163
+ needs: [linux-x86, linux-arm, macos, windows, sdist]
164
+ environment:
165
+ name: pypi
166
+ url: https://pypi.org/project/survival
167
+ steps:
168
+ - uses: actions/checkout@v6
169
+ with:
170
+ ref: ${{ github.event_name == 'push' && 'main' || github.ref }}
171
+
172
+ - name: Get version from Cargo.toml
173
+ id: version
174
+ run: |
175
+ VERSION=$(grep '^version' Cargo.toml | head -1 | sed 's/.*"\(.*\)".*/\1/')
176
+ echo "version=$VERSION" >> $GITHUB_OUTPUT
177
+
178
+ - name: Check if version exists on PyPI
179
+ id: check
180
+ run: |
181
+ if curl -s "https://pypi.org/pypi/survival/${{ steps.version.outputs.version }}/json" | grep -q '"version"'; then
182
+ echo "exists=true" >> $GITHUB_OUTPUT
183
+ echo "Version ${{ steps.version.outputs.version }} already exists on PyPI, skipping publish"
184
+ else
185
+ echo "exists=false" >> $GITHUB_OUTPUT
186
+ echo "Version ${{ steps.version.outputs.version }} not found on PyPI, will publish"
187
+ fi
188
+
189
+ - uses: actions/download-artifact@v7
190
+ if: steps.check.outputs.exists == 'false'
191
+ with:
192
+ path: dist
193
+ merge-multiple: true
194
+
195
+ - name: Publish to PyPI
196
+ if: steps.check.outputs.exists == 'false'
197
+ uses: pypa/gh-action-pypi-publish@release/v1
198
+ with:
199
+ password: ${{ secrets.PYPI_API_TOKEN }}
200
+
201
+ publish-crates:
202
+ name: Publish to crates.io
203
+ runs-on: ubuntu-latest
204
+ if: github.event_name == 'push' || github.event_name == 'release'
205
+ steps:
206
+ - uses: actions/checkout@v6
207
+ with:
208
+ ref: ${{ github.event_name == 'push' && 'main' || github.ref }}
209
+
210
+ - name: Install Rust
211
+ uses: dtolnay/rust-toolchain@stable
212
+
213
+ - name: Get version from Cargo.toml
214
+ id: version
215
+ run: |
216
+ VERSION=$(grep '^version' Cargo.toml | head -1 | sed 's/.*"\(.*\)".*/\1/')
217
+ echo "version=$VERSION" >> $GITHUB_OUTPUT
218
+
219
+ - name: Check if version exists on crates.io
220
+ id: check
221
+ run: |
222
+ if curl -s "https://crates.io/api/v1/crates/survival/${{ steps.version.outputs.version }}" | grep -q '"version"'; then
223
+ echo "exists=true" >> $GITHUB_OUTPUT
224
+ echo "Version ${{ steps.version.outputs.version }} already exists on crates.io, skipping publish"
225
+ else
226
+ echo "exists=false" >> $GITHUB_OUTPUT
227
+ echo "Version ${{ steps.version.outputs.version }} not found on crates.io, will publish"
228
+ fi
229
+
230
+ - name: Publish to crates.io
231
+ if: steps.check.outputs.exists == 'false'
232
+ run: cargo publish --no-verify --allow-dirty
233
+ env:
234
+ CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
@@ -0,0 +1,45 @@
1
+ name: Release
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ workflow_dispatch:
7
+
8
+ permissions:
9
+ contents: write
10
+
11
+ jobs:
12
+ release:
13
+ name: Create GitHub Release
14
+ runs-on: ubuntu-latest
15
+ steps:
16
+ - uses: actions/checkout@v6
17
+ with:
18
+ fetch-depth: 0
19
+
20
+ - name: Get version from Cargo.toml
21
+ id: version
22
+ run: |
23
+ VERSION=$(grep '^version' Cargo.toml | head -1 | sed 's/.*"\(.*\)".*/\1/')
24
+ echo "version=$VERSION" >> $GITHUB_OUTPUT
25
+ echo "tag=v$VERSION" >> $GITHUB_OUTPUT
26
+
27
+ - name: Check if tag exists
28
+ id: check
29
+ run: |
30
+ if git rev-parse "v${{ steps.version.outputs.version }}" >/dev/null 2>&1; then
31
+ echo "exists=true" >> $GITHUB_OUTPUT
32
+ echo "Tag v${{ steps.version.outputs.version }} already exists"
33
+ else
34
+ echo "exists=false" >> $GITHUB_OUTPUT
35
+ echo "Tag v${{ steps.version.outputs.version }} does not exist, will create release"
36
+ fi
37
+
38
+ - name: Create GitHub Release
39
+ if: steps.check.outputs.exists == 'false'
40
+ run: |
41
+ gh release create "${{ steps.version.outputs.tag }}" \
42
+ --title "${{ steps.version.outputs.tag }}" \
43
+ --generate-notes
44
+ env:
45
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -0,0 +1,185 @@
1
+ name: CI
2
+
3
+ on:
4
+ pull_request:
5
+ branches: [main]
6
+
7
+ env:
8
+ CARGO_TERM_COLOR: always
9
+ RUST_BACKTRACE: 1
10
+
11
+ jobs:
12
+ build-and-test:
13
+ name: Build & Test (${{ matrix.os }})
14
+ runs-on: ${{ matrix.os }}
15
+ strategy:
16
+ fail-fast: false
17
+ matrix:
18
+ os: [ubuntu-latest, macos-latest, windows-latest]
19
+
20
+ steps:
21
+ - name: Checkout code
22
+ uses: actions/checkout@v6
23
+
24
+ - name: Set up Python
25
+ uses: actions/setup-python@v6
26
+ with:
27
+ python-version: '3.14'
28
+
29
+ - name: Install Rust
30
+ uses: dtolnay/rust-toolchain@stable
31
+
32
+ - name: Cache Rust dependencies
33
+ uses: actions/cache@v5
34
+ with:
35
+ path: |
36
+ ~/.cargo/bin/
37
+ ~/.cargo/registry/index/
38
+ ~/.cargo/registry/cache/
39
+ ~/.cargo/git/db/
40
+ target/
41
+ key: ${{ runner.os }}-cargo-py3.14-${{ hashFiles('**/Cargo.lock') }}
42
+ restore-keys: |
43
+ ${{ runner.os }}-cargo-py3.14-
44
+
45
+ - name: Install maturin and test dependencies
46
+ run: pip install maturin numpy pandas polars
47
+
48
+ - name: Clean old wheels
49
+ run: rm -rf target/wheels || true
50
+ shell: bash
51
+
52
+ - name: Build with maturin
53
+ run: maturin build --release --interpreter python --features extension-module
54
+
55
+ - name: Run Rust tests
56
+ if: matrix.os == 'ubuntu-latest'
57
+ run: cargo test --release
58
+
59
+ - name: Install wheel (Unix)
60
+ if: matrix.os != 'windows-latest'
61
+ run: pip install target/wheels/survival-*.whl
62
+
63
+ - name: Install wheel (Windows)
64
+ if: matrix.os == 'windows-latest'
65
+ run: |
66
+ $wheel = Get-ChildItem -Path target/wheels -Filter "survival-*.whl" | Select-Object -First 1
67
+ pip install $wheel.FullName
68
+
69
+ - name: Run Python tests
70
+ run: python test/test_all.py
71
+
72
+ python-matrix:
73
+ name: Python ${{ matrix.python-version }}
74
+ runs-on: ubuntu-latest
75
+ strategy:
76
+ fail-fast: false
77
+ matrix:
78
+ python-version: ['3.14']
79
+
80
+ steps:
81
+ - name: Checkout code
82
+ uses: actions/checkout@v6
83
+
84
+ - name: Set up Python ${{ matrix.python-version }}
85
+ uses: actions/setup-python@v6
86
+ with:
87
+ python-version: ${{ matrix.python-version }}
88
+
89
+ - name: Install Rust
90
+ uses: dtolnay/rust-toolchain@stable
91
+
92
+ - name: Cache Rust dependencies
93
+ uses: actions/cache@v5
94
+ with:
95
+ path: |
96
+ ~/.cargo/bin/
97
+ ~/.cargo/registry/index/
98
+ ~/.cargo/registry/cache/
99
+ ~/.cargo/git/db/
100
+ target/
101
+ key: ${{ runner.os }}-cargo-py${{ matrix.python-version }}-${{ hashFiles('**/Cargo.lock') }}
102
+ restore-keys: |
103
+ ${{ runner.os }}-cargo-py${{ matrix.python-version }}-
104
+
105
+ - name: Install maturin and test dependencies
106
+ run: pip install maturin numpy pandas polars
107
+
108
+ - name: Clean old wheels
109
+ run: rm -rf target/wheels || true
110
+
111
+ - name: Build and install
112
+ run: |
113
+ maturin build --release --interpreter python --features extension-module
114
+ pip install target/wheels/survival-*.whl
115
+
116
+ - name: Run Rust tests
117
+ run: cargo test --release
118
+
119
+ - name: Run Python tests
120
+ run: python test/test_all.py
121
+
122
+ r-validation:
123
+ name: R Survival Package Validation
124
+ runs-on: ubuntu-latest
125
+ steps:
126
+ - name: Checkout code
127
+ uses: actions/checkout@v6
128
+
129
+ - name: Install R
130
+ uses: r-lib/actions/setup-r@v2
131
+ with:
132
+ r-version: '4.5.2'
133
+
134
+ - name: Install R dependencies
135
+ run: |
136
+ install.packages(c("survival", "jsonlite"), repos = "https://cloud.r-project.org")
137
+ shell: Rscript {0}
138
+
139
+ - name: Regenerate expected values
140
+ run: |
141
+ cd test
142
+ Rscript generate_r_expected_values.R
143
+
144
+ - name: Check for differences
145
+ run: |
146
+ if git diff --exit-code test/r_expected_values.json; then
147
+ echo "✓ R expected values are up to date"
148
+ else
149
+ echo "✗ R expected values have changed!"
150
+ echo "Please run 'Rscript test/generate_r_expected_values.R' and commit the changes"
151
+ exit 1
152
+ fi
153
+
154
+ docs:
155
+ name: Documentation
156
+ runs-on: ubuntu-latest
157
+ steps:
158
+ - name: Checkout code
159
+ uses: actions/checkout@v6
160
+
161
+ - name: Set up Python
162
+ uses: actions/setup-python@v6
163
+ with:
164
+ python-version: '3.14'
165
+
166
+ - name: Install Rust
167
+ uses: dtolnay/rust-toolchain@stable
168
+
169
+ - name: Cache Rust dependencies
170
+ uses: actions/cache@v5
171
+ with:
172
+ path: |
173
+ ~/.cargo/bin/
174
+ ~/.cargo/registry/index/
175
+ ~/.cargo/registry/cache/
176
+ ~/.cargo/git/db/
177
+ target/
178
+ key: ${{ runner.os }}-cargo-docs-${{ hashFiles('**/Cargo.lock') }}
179
+ restore-keys: |
180
+ ${{ runner.os }}-cargo-
181
+
182
+ - name: Build documentation
183
+ run: cargo doc --no-deps
184
+ env:
185
+ RUSTDOCFLAGS: -D warnings
@@ -0,0 +1,38 @@
1
+ name: Security Audit
2
+
3
+ on:
4
+ pull_request:
5
+ branches: [main]
6
+
7
+ permissions:
8
+ contents: read
9
+
10
+ jobs:
11
+ audit:
12
+ name: Security Audit
13
+ runs-on: ubuntu-latest
14
+ steps:
15
+ - name: Checkout code
16
+ uses: actions/checkout@v6
17
+
18
+ - name: Install Rust
19
+ uses: dtolnay/rust-toolchain@stable
20
+
21
+ - name: Install cargo-audit
22
+ run: cargo install cargo-audit
23
+
24
+ - name: Run security audit
25
+ run: cargo audit
26
+
27
+ dependency-review:
28
+ name: Dependency Review
29
+ runs-on: ubuntu-latest
30
+ if: github.event_name == 'pull_request'
31
+ steps:
32
+ - name: Checkout code
33
+ uses: actions/checkout@v6
34
+
35
+ - name: Dependency Review
36
+ uses: actions/dependency-review-action@v4
37
+ with:
38
+ fail-on-severity: high
@@ -0,0 +1,43 @@
1
+ name: Version Bump
2
+
3
+ on:
4
+ pull_request:
5
+ branches: [main]
6
+
7
+ permissions:
8
+ contents: write
9
+
10
+ jobs:
11
+ bump-version:
12
+ name: Bump Version
13
+ runs-on: ubuntu-latest
14
+ steps:
15
+ - uses: actions/checkout@v6
16
+ with:
17
+ token: ${{ secrets.PAT_TOKEN || secrets.GITHUB_TOKEN }}
18
+ ref: ${{ github.head_ref }}
19
+
20
+ - name: Check and bump version if needed
21
+ run: |
22
+ CURRENT=$(grep '^version' Cargo.toml | head -1 | sed 's/.*"\(.*\)".*/\1/')
23
+ echo "Current version: $CURRENT"
24
+
25
+ if curl -s "https://pypi.org/pypi/survival/$CURRENT/json" | grep -q '"version"'; then
26
+ echo "Version $CURRENT exists on PyPI, bumping patch version"
27
+
28
+ IFS='.' read -r major minor patch <<< "$CURRENT"
29
+ NEW_VERSION="$major.$minor.$((patch + 1))"
30
+ echo "New version: $NEW_VERSION"
31
+
32
+ sed -i "s/^version = \"$CURRENT\"/version = \"$NEW_VERSION\"/" Cargo.toml
33
+
34
+ sed -i "s/^version = \"$CURRENT\"/version = \"$NEW_VERSION\"/" pyproject.toml
35
+
36
+ git config user.name "github-actions[bot]"
37
+ git config user.email "github-actions[bot]@users.noreply.github.com"
38
+ git add Cargo.toml pyproject.toml
39
+ git commit -m "Bump version to $NEW_VERSION"
40
+ git push
41
+ else
42
+ echo "Version $CURRENT is new, no bump needed"
43
+ fi
@@ -0,0 +1,25 @@
1
+ # Virtualenv
2
+ .venv/
3
+ venv/
4
+ ENV/
5
+
6
+ # Test extraction directory
7
+ .test_wheel_extract/
8
+
9
+ # Python cache
10
+ __pycache__/
11
+ *.pyc
12
+ *.pyo
13
+ *.pyd
14
+ .Python
15
+
16
+ # Rust build artifacts
17
+ target/
18
+ Cargo.lock
19
+
20
+ # IDE
21
+ .vscode/
22
+ .idea/
23
+ *.swp
24
+ *.swo
25
+ *~