splitiq 0.5.2__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.
- splitiq-0.5.2/PKG-INFO +153 -0
- splitiq-0.5.2/README.md +125 -0
- splitiq-0.5.2/pyproject.toml +261 -0
- splitiq-0.5.2/pyproject.toml.orig +284 -0
- splitiq-0.5.2/src/splitiq/__init__.py +27 -0
- splitiq-0.5.2/src/splitiq/_convert.py +190 -0
- splitiq-0.5.2/src/splitiq/_julia.py +91 -0
- splitiq-0.5.2/src/splitiq/_version.py +32 -0
- splitiq-0.5.2/src/splitiq/estimators.py +108 -0
- splitiq-0.5.2/src/splitiq/juliapkg.json +10 -0
- splitiq-0.5.2/src/splitiq/quality.py +166 -0
- splitiq-0.5.2/src/splitiq/ratio.py +50 -0
- splitiq-0.5.2/src/splitiq/split.py +208 -0
splitiq-0.5.2/PKG-INFO
ADDED
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: splitiq
|
|
3
|
+
Version: 0.5.2
|
|
4
|
+
Summary: Optimal train/test splitting via support points, backed by SPlit.jl
|
|
5
|
+
Keywords: data splitting,support points,energy distance,train test split,julia
|
|
6
|
+
Author: Jongsu Liam Kim
|
|
7
|
+
Author-email: Jongsu Liam Kim <jongsukim8@gmail.com>
|
|
8
|
+
License-Expression: Apache-2.0
|
|
9
|
+
Classifier: Development Status :: 3 - Alpha
|
|
10
|
+
Classifier: Intended Audience :: Developers
|
|
11
|
+
Classifier: Intended Audience :: Science/Research
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
15
|
+
Classifier: Operating System :: POSIX
|
|
16
|
+
Classifier: Topic :: Scientific/Engineering
|
|
17
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
18
|
+
Requires-Dist: juliacall>=0.9.35,<0.10
|
|
19
|
+
Requires-Dist: juliapkg>=0.1.26,<0.2
|
|
20
|
+
Requires-Dist: numpy>=1.26
|
|
21
|
+
Requires-Dist: pandas>=2.0 ; extra == 'pandas'
|
|
22
|
+
Requires-Python: >=3.12, <4.0
|
|
23
|
+
Project-URL: Homepage, https://github.com/appleparan/SPlit.jl
|
|
24
|
+
Project-URL: Documentation, https://appleparan.github.io/SPlit.jl
|
|
25
|
+
Project-URL: Issues, https://github.com/appleparan/SPlit.jl/issues
|
|
26
|
+
Provides-Extra: pandas
|
|
27
|
+
Description-Content-Type: text/markdown
|
|
28
|
+
|
|
29
|
+
# splitiq
|
|
30
|
+
|
|
31
|
+
`splitiq` is a Python wrapper around [SPlit.jl](https://github.com/appleparan/SPlit.jl), a
|
|
32
|
+
Julia package for optimal train/test splitting via support points. All computation runs in
|
|
33
|
+
Julia through [juliacall](https://github.com/JuliaPy/PythonCall.jl); `splitiq` only converts
|
|
34
|
+
data in and out and translates errors, so its results and guarantees are those of SPlit.jl.
|
|
35
|
+
|
|
36
|
+
## Installation
|
|
37
|
+
|
|
38
|
+
Install with [uv](https://docs.astral.sh/uv/):
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
uv add splitiq
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Add the `pandas` extra for DataFrame input:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
uv add "splitiq[pandas]"
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
If you are not using uv, `pip` works as well:
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
pip install splitiq # or: pip install "splitiq[pandas]"
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Python 3.12 or later is required.
|
|
57
|
+
|
|
58
|
+
## Quick start
|
|
59
|
+
|
|
60
|
+
```python
|
|
61
|
+
import numpy as np
|
|
62
|
+
import splitiq
|
|
63
|
+
|
|
64
|
+
X = np.random.default_rng(1).standard_normal((1_000, 3))
|
|
65
|
+
result = splitiq.datasplit(X, ratio=0.2, seed=2)
|
|
66
|
+
|
|
67
|
+
train, test = result.apply(X) # or X[result.train_indices], X[result.test_indices]
|
|
68
|
+
splitiq.splitquality(X, result) # energy distance between train and test; lower is better
|
|
69
|
+
splitiq.optimal_split_ratio(X[:, :2], X[:, 2])
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
`datasplit` also accepts a pandas DataFrame. `category` columns keep their category order;
|
|
73
|
+
plain string/object columns are encoded using their sorted unique values as levels:
|
|
74
|
+
|
|
75
|
+
```python
|
|
76
|
+
import pandas as pd
|
|
77
|
+
|
|
78
|
+
df = pd.DataFrame({'x': X[:, 0], 'g': pd.Categorical(['a', 'b', 'c'] * (len(X) // 3))})
|
|
79
|
+
result = splitiq.datasplit(df, ratio=0.2, seed=2)
|
|
80
|
+
train, test = result.apply(df) # df.iloc[result.train_indices], df.iloc[result.test_indices]
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## API
|
|
84
|
+
|
|
85
|
+
| Function | Description |
|
|
86
|
+
| --- | --- |
|
|
87
|
+
| `datasplit(data, ratio=0.2, *, method, kernel, bandwidth, kappa, max_iterations, tolerance, n_threads, seed)` | Split `data` into train/test sets whose distributions match closely; returns a `SplitResult`. |
|
|
88
|
+
| `SplitResult` | `train_indices`, `test_indices` (0-based numpy arrays), `converged`, `iterations`, `method`, `kernel`, `bandwidth`, `ratio`; `.apply(data)` returns `(train, test)`; supports `train_idx, test_idx = result`. |
|
|
89
|
+
| `splitquality(data, result, *, kernel, bandwidth, estimator, exact_threshold, seed, n_threads)` | Discrepancy between the train and test rows of `data`; lower is better. |
|
|
90
|
+
| `energydistance(x, y, *, estimator, seed, n_threads)` | Energy distance between two samples. |
|
|
91
|
+
| `mmd(x, y, kernel='gaussian', *, bandwidth, estimator, seed, n_threads)` | Squared maximum mean discrepancy between two samples. |
|
|
92
|
+
| `Exact()`, `Subsample(m, repeats=8)`, `RandomSlices(k)`, `RandomFeatures(D)` | Discrepancy estimators for `energydistance`/`mmd`/`splitquality`. |
|
|
93
|
+
| `optimal_split_ratio(x, y, *, method='simple', degree=2)` | Optimal test-set fraction `gamma = 1 / (sqrt(p) + 1)`. |
|
|
94
|
+
|
|
95
|
+
`method='support_points'` runs the Mak & Joseph (2018) / Joseph & Vakayil (2021) optimizer;
|
|
96
|
+
`method='herding'` runs greedy kernel herding. Indices are 0-based. A Julia `ArgumentError`
|
|
97
|
+
surfaces as a Python `ValueError`; other Julia errors propagate as `juliacall.JuliaError`.
|
|
98
|
+
See the docstrings under `src/splitiq/` for the full argument reference, or build the API
|
|
99
|
+
reference locally with `make docs`.
|
|
100
|
+
|
|
101
|
+
## First call and threads
|
|
102
|
+
|
|
103
|
+
Julia does not start when you `import splitiq`. It starts on the first call to `datasplit`,
|
|
104
|
+
`splitquality`, or any other function that needs it. On that first call, `juliapkg` installs a
|
|
105
|
+
compatible Julia (>= 1.10, via `juliaup`) if none is on the `PATH`, instantiates SPlit.jl from
|
|
106
|
+
git, and precompiles it. This one-time step takes a few minutes. Later starts (a new process
|
|
107
|
+
picking up the already-installed Julia and the precompiled package) take about two seconds.
|
|
108
|
+
|
|
109
|
+
Julia runs single-threaded inside Python unless `PYTHON_JULIACALL_THREADS` (e.g. `auto`, or a
|
|
110
|
+
number) is set in the environment before the first call. The `n_threads` keyword argument only
|
|
111
|
+
limits parallelism within the threads Julia was started with; it cannot raise that count.
|
|
112
|
+
|
|
113
|
+
## Versioning and releases
|
|
114
|
+
|
|
115
|
+
The `splitiq` version tracks the SPlit.jl version (currently 0.5.2); `src/splitiq/juliapkg.json`
|
|
116
|
+
pins SPlit.jl at the git tag `v<version>`. Pushing a `vX.Y.Z` release tag builds the versioned
|
|
117
|
+
Julia documentation and, through the `PythonPublish` workflow, publishes `splitiq` to PyPI, so
|
|
118
|
+
both releases come from one tag. There is no separate changelog or release script for the
|
|
119
|
+
Python package.
|
|
120
|
+
|
|
121
|
+
## Development
|
|
122
|
+
|
|
123
|
+
From the `splitiq/` directory:
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
uv sync --group dev --group docs # install dependencies
|
|
127
|
+
make julia-dev # build .julia_dev/, developing SPlit.jl from this checkout
|
|
128
|
+
make test # run pytest against .julia_dev/
|
|
129
|
+
make format # ruff format
|
|
130
|
+
make lint # ruff check --fix
|
|
131
|
+
make typecheck # ty check
|
|
132
|
+
make docs # properdocs build --strict
|
|
133
|
+
make build # uv build
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
`make julia-dev` runs `scripts/setup_julia_dev.sh`, which develops SPlit.jl from the repository
|
|
137
|
+
checkout instead of the git-pinned revision in `juliapkg.json`, and pins `PythonCall` to the
|
|
138
|
+
version `juliacall` itself requires. `make test` runs against that project by setting
|
|
139
|
+
`PYTHON_JULIACALL_PROJECT`/`PYTHON_JULIACALL_EXE`.
|
|
140
|
+
|
|
141
|
+
Pre-commit hooks are configured at the repository root and run from there
|
|
142
|
+
(`uvx pre-commit run -a`), not from `splitiq/`.
|
|
143
|
+
|
|
144
|
+
## References
|
|
145
|
+
|
|
146
|
+
- Mak, S. & Joseph, V. R. (2018). Support points. *Annals of Statistics*, 46(6A).
|
|
147
|
+
- Joseph, V. R. & Vakayil, A. (2021). SPlit: An optimal method for data splitting.
|
|
148
|
+
*Technometrics*, 63(4).
|
|
149
|
+
- Joseph, V. R. (2022). Optimal ratio for data splitting. *Statistical Analysis and Data
|
|
150
|
+
Mining*, 15(4).
|
|
151
|
+
- Chen, Y., Welling, M. & Smola, A. (2010). Super-samples from kernel herding. *UAI*.
|
|
152
|
+
|
|
153
|
+
This project template is generated by [copier-modern-ml](https://github.com/appleparan/copier-modern-ml).
|
splitiq-0.5.2/README.md
ADDED
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
# splitiq
|
|
2
|
+
|
|
3
|
+
`splitiq` is a Python wrapper around [SPlit.jl](https://github.com/appleparan/SPlit.jl), a
|
|
4
|
+
Julia package for optimal train/test splitting via support points. All computation runs in
|
|
5
|
+
Julia through [juliacall](https://github.com/JuliaPy/PythonCall.jl); `splitiq` only converts
|
|
6
|
+
data in and out and translates errors, so its results and guarantees are those of SPlit.jl.
|
|
7
|
+
|
|
8
|
+
## Installation
|
|
9
|
+
|
|
10
|
+
Install with [uv](https://docs.astral.sh/uv/):
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
uv add splitiq
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
Add the `pandas` extra for DataFrame input:
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
uv add "splitiq[pandas]"
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
If you are not using uv, `pip` works as well:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
pip install splitiq # or: pip install "splitiq[pandas]"
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Python 3.12 or later is required.
|
|
29
|
+
|
|
30
|
+
## Quick start
|
|
31
|
+
|
|
32
|
+
```python
|
|
33
|
+
import numpy as np
|
|
34
|
+
import splitiq
|
|
35
|
+
|
|
36
|
+
X = np.random.default_rng(1).standard_normal((1_000, 3))
|
|
37
|
+
result = splitiq.datasplit(X, ratio=0.2, seed=2)
|
|
38
|
+
|
|
39
|
+
train, test = result.apply(X) # or X[result.train_indices], X[result.test_indices]
|
|
40
|
+
splitiq.splitquality(X, result) # energy distance between train and test; lower is better
|
|
41
|
+
splitiq.optimal_split_ratio(X[:, :2], X[:, 2])
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
`datasplit` also accepts a pandas DataFrame. `category` columns keep their category order;
|
|
45
|
+
plain string/object columns are encoded using their sorted unique values as levels:
|
|
46
|
+
|
|
47
|
+
```python
|
|
48
|
+
import pandas as pd
|
|
49
|
+
|
|
50
|
+
df = pd.DataFrame({'x': X[:, 0], 'g': pd.Categorical(['a', 'b', 'c'] * (len(X) // 3))})
|
|
51
|
+
result = splitiq.datasplit(df, ratio=0.2, seed=2)
|
|
52
|
+
train, test = result.apply(df) # df.iloc[result.train_indices], df.iloc[result.test_indices]
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## API
|
|
56
|
+
|
|
57
|
+
| Function | Description |
|
|
58
|
+
| --- | --- |
|
|
59
|
+
| `datasplit(data, ratio=0.2, *, method, kernel, bandwidth, kappa, max_iterations, tolerance, n_threads, seed)` | Split `data` into train/test sets whose distributions match closely; returns a `SplitResult`. |
|
|
60
|
+
| `SplitResult` | `train_indices`, `test_indices` (0-based numpy arrays), `converged`, `iterations`, `method`, `kernel`, `bandwidth`, `ratio`; `.apply(data)` returns `(train, test)`; supports `train_idx, test_idx = result`. |
|
|
61
|
+
| `splitquality(data, result, *, kernel, bandwidth, estimator, exact_threshold, seed, n_threads)` | Discrepancy between the train and test rows of `data`; lower is better. |
|
|
62
|
+
| `energydistance(x, y, *, estimator, seed, n_threads)` | Energy distance between two samples. |
|
|
63
|
+
| `mmd(x, y, kernel='gaussian', *, bandwidth, estimator, seed, n_threads)` | Squared maximum mean discrepancy between two samples. |
|
|
64
|
+
| `Exact()`, `Subsample(m, repeats=8)`, `RandomSlices(k)`, `RandomFeatures(D)` | Discrepancy estimators for `energydistance`/`mmd`/`splitquality`. |
|
|
65
|
+
| `optimal_split_ratio(x, y, *, method='simple', degree=2)` | Optimal test-set fraction `gamma = 1 / (sqrt(p) + 1)`. |
|
|
66
|
+
|
|
67
|
+
`method='support_points'` runs the Mak & Joseph (2018) / Joseph & Vakayil (2021) optimizer;
|
|
68
|
+
`method='herding'` runs greedy kernel herding. Indices are 0-based. A Julia `ArgumentError`
|
|
69
|
+
surfaces as a Python `ValueError`; other Julia errors propagate as `juliacall.JuliaError`.
|
|
70
|
+
See the docstrings under `src/splitiq/` for the full argument reference, or build the API
|
|
71
|
+
reference locally with `make docs`.
|
|
72
|
+
|
|
73
|
+
## First call and threads
|
|
74
|
+
|
|
75
|
+
Julia does not start when you `import splitiq`. It starts on the first call to `datasplit`,
|
|
76
|
+
`splitquality`, or any other function that needs it. On that first call, `juliapkg` installs a
|
|
77
|
+
compatible Julia (>= 1.10, via `juliaup`) if none is on the `PATH`, instantiates SPlit.jl from
|
|
78
|
+
git, and precompiles it. This one-time step takes a few minutes. Later starts (a new process
|
|
79
|
+
picking up the already-installed Julia and the precompiled package) take about two seconds.
|
|
80
|
+
|
|
81
|
+
Julia runs single-threaded inside Python unless `PYTHON_JULIACALL_THREADS` (e.g. `auto`, or a
|
|
82
|
+
number) is set in the environment before the first call. The `n_threads` keyword argument only
|
|
83
|
+
limits parallelism within the threads Julia was started with; it cannot raise that count.
|
|
84
|
+
|
|
85
|
+
## Versioning and releases
|
|
86
|
+
|
|
87
|
+
The `splitiq` version tracks the SPlit.jl version (currently 0.5.2); `src/splitiq/juliapkg.json`
|
|
88
|
+
pins SPlit.jl at the git tag `v<version>`. Pushing a `vX.Y.Z` release tag builds the versioned
|
|
89
|
+
Julia documentation and, through the `PythonPublish` workflow, publishes `splitiq` to PyPI, so
|
|
90
|
+
both releases come from one tag. There is no separate changelog or release script for the
|
|
91
|
+
Python package.
|
|
92
|
+
|
|
93
|
+
## Development
|
|
94
|
+
|
|
95
|
+
From the `splitiq/` directory:
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
uv sync --group dev --group docs # install dependencies
|
|
99
|
+
make julia-dev # build .julia_dev/, developing SPlit.jl from this checkout
|
|
100
|
+
make test # run pytest against .julia_dev/
|
|
101
|
+
make format # ruff format
|
|
102
|
+
make lint # ruff check --fix
|
|
103
|
+
make typecheck # ty check
|
|
104
|
+
make docs # properdocs build --strict
|
|
105
|
+
make build # uv build
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
`make julia-dev` runs `scripts/setup_julia_dev.sh`, which develops SPlit.jl from the repository
|
|
109
|
+
checkout instead of the git-pinned revision in `juliapkg.json`, and pins `PythonCall` to the
|
|
110
|
+
version `juliacall` itself requires. `make test` runs against that project by setting
|
|
111
|
+
`PYTHON_JULIACALL_PROJECT`/`PYTHON_JULIACALL_EXE`.
|
|
112
|
+
|
|
113
|
+
Pre-commit hooks are configured at the repository root and run from there
|
|
114
|
+
(`uvx pre-commit run -a`), not from `splitiq/`.
|
|
115
|
+
|
|
116
|
+
## References
|
|
117
|
+
|
|
118
|
+
- Mak, S. & Joseph, V. R. (2018). Support points. *Annals of Statistics*, 46(6A).
|
|
119
|
+
- Joseph, V. R. & Vakayil, A. (2021). SPlit: An optimal method for data splitting.
|
|
120
|
+
*Technometrics*, 63(4).
|
|
121
|
+
- Joseph, V. R. (2022). Optimal ratio for data splitting. *Statistical Analysis and Data
|
|
122
|
+
Mining*, 15(4).
|
|
123
|
+
- Chen, Y., Welling, M. & Smola, A. (2010). Super-samples from kernel herding. *UAI*.
|
|
124
|
+
|
|
125
|
+
This project template is generated by [copier-modern-ml](https://github.com/appleparan/copier-modern-ml).
|
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "splitiq"
|
|
3
|
+
version = "0.5.2"
|
|
4
|
+
description = "Optimal train/test splitting via support points, backed by SPlit.jl"
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
license = "Apache-2.0"
|
|
7
|
+
dependencies = [
|
|
8
|
+
"juliacall>=0.9.35,<0.10",
|
|
9
|
+
"juliapkg>=0.1.26,<0.2",
|
|
10
|
+
"numpy>=1.26",
|
|
11
|
+
]
|
|
12
|
+
requires-python = ">=3.12, <4.0"
|
|
13
|
+
keywords = [
|
|
14
|
+
"data splitting",
|
|
15
|
+
"support points",
|
|
16
|
+
"energy distance",
|
|
17
|
+
"train test split",
|
|
18
|
+
"julia",
|
|
19
|
+
]
|
|
20
|
+
classifiers = [
|
|
21
|
+
"Development Status :: 3 - Alpha",
|
|
22
|
+
"Intended Audience :: Developers",
|
|
23
|
+
"Intended Audience :: Science/Research",
|
|
24
|
+
"Programming Language :: Python :: 3.12",
|
|
25
|
+
"Programming Language :: Python :: 3.13",
|
|
26
|
+
"Programming Language :: Python :: 3.14",
|
|
27
|
+
"Operating System :: POSIX",
|
|
28
|
+
"Topic :: Scientific/Engineering",
|
|
29
|
+
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
30
|
+
]
|
|
31
|
+
|
|
32
|
+
[[project.authors]]
|
|
33
|
+
name = "Jongsu Liam Kim"
|
|
34
|
+
email = "jongsukim8@gmail.com"
|
|
35
|
+
|
|
36
|
+
[project.urls]
|
|
37
|
+
Homepage = "https://github.com/appleparan/SPlit.jl"
|
|
38
|
+
Documentation = "https://appleparan.github.io/SPlit.jl"
|
|
39
|
+
Issues = "https://github.com/appleparan/SPlit.jl/issues"
|
|
40
|
+
|
|
41
|
+
[project.optional-dependencies]
|
|
42
|
+
pandas = ["pandas>=2.0"]
|
|
43
|
+
|
|
44
|
+
[dependency-groups]
|
|
45
|
+
dev = [
|
|
46
|
+
{ include-group = "docs" },
|
|
47
|
+
"coverage==7.15.4",
|
|
48
|
+
"pandas>=2.0",
|
|
49
|
+
"coverage-badge==1.1.2",
|
|
50
|
+
"git-cliff==2.13.1",
|
|
51
|
+
"ruff==0.16.4",
|
|
52
|
+
"pytest==9.1.1",
|
|
53
|
+
"pytest-cov==7.1.0",
|
|
54
|
+
"pytest-html==4.2.0",
|
|
55
|
+
"pytest-mock==3.15.1",
|
|
56
|
+
"pre-commit==4.6.2",
|
|
57
|
+
"ty>=0.0.74",
|
|
58
|
+
]
|
|
59
|
+
docs = [
|
|
60
|
+
"properdocs==1.6.7",
|
|
61
|
+
"mkdocs-materialx==10.2.0",
|
|
62
|
+
"mkdocstrings[python]==1.0.6",
|
|
63
|
+
"mkdocs-gen-files==0.6.1",
|
|
64
|
+
"mkdocs-section-index==0.3.12",
|
|
65
|
+
"mkdocs-literate-nav==0.6.3",
|
|
66
|
+
]
|
|
67
|
+
|
|
68
|
+
[build-system]
|
|
69
|
+
requires = ["uv_build>=0.12.4,<0.13"]
|
|
70
|
+
build-backend = "uv_build"
|
|
71
|
+
|
|
72
|
+
[tool.uv]
|
|
73
|
+
package = true
|
|
74
|
+
managed = true
|
|
75
|
+
exclude-newer = "P7D"
|
|
76
|
+
|
|
77
|
+
[tool.uv.pip]
|
|
78
|
+
index-url = "https://pypi.org/simple"
|
|
79
|
+
|
|
80
|
+
[tool.ruff]
|
|
81
|
+
include = [
|
|
82
|
+
"*.py",
|
|
83
|
+
"*.pyi",
|
|
84
|
+
"**/pyproject.toml",
|
|
85
|
+
"*.ipynb",
|
|
86
|
+
]
|
|
87
|
+
exclude = [
|
|
88
|
+
"__pycache__",
|
|
89
|
+
"data/*",
|
|
90
|
+
"notebooks/*",
|
|
91
|
+
"logs/*",
|
|
92
|
+
"**/__pycache__",
|
|
93
|
+
".bzr",
|
|
94
|
+
".direnv",
|
|
95
|
+
".eggs",
|
|
96
|
+
".git",
|
|
97
|
+
".git-rewrite",
|
|
98
|
+
".hg",
|
|
99
|
+
".nox",
|
|
100
|
+
".pants.d",
|
|
101
|
+
".pytype",
|
|
102
|
+
".ruff_cache",
|
|
103
|
+
".svn",
|
|
104
|
+
".tox",
|
|
105
|
+
".venv",
|
|
106
|
+
"__pypackages__",
|
|
107
|
+
"_build",
|
|
108
|
+
"buck-out",
|
|
109
|
+
"build",
|
|
110
|
+
"dist",
|
|
111
|
+
"node_modules",
|
|
112
|
+
"venv",
|
|
113
|
+
"docs",
|
|
114
|
+
"data",
|
|
115
|
+
"tests/data",
|
|
116
|
+
]
|
|
117
|
+
line-length = 100
|
|
118
|
+
target-version = "py313"
|
|
119
|
+
|
|
120
|
+
[tool.ruff.lint]
|
|
121
|
+
ignore = [
|
|
122
|
+
"ANN002",
|
|
123
|
+
"ANN003",
|
|
124
|
+
"ANN204",
|
|
125
|
+
"COM812",
|
|
126
|
+
"D100",
|
|
127
|
+
"D101",
|
|
128
|
+
"E741",
|
|
129
|
+
"F811",
|
|
130
|
+
"FBT001",
|
|
131
|
+
"FBT002",
|
|
132
|
+
"N806",
|
|
133
|
+
]
|
|
134
|
+
select = [
|
|
135
|
+
"A",
|
|
136
|
+
"AIR",
|
|
137
|
+
"ANN",
|
|
138
|
+
"ARG",
|
|
139
|
+
"B",
|
|
140
|
+
"BLE",
|
|
141
|
+
"B9",
|
|
142
|
+
"COM",
|
|
143
|
+
"C4",
|
|
144
|
+
"D",
|
|
145
|
+
"DTZ",
|
|
146
|
+
"E",
|
|
147
|
+
"EM",
|
|
148
|
+
"F",
|
|
149
|
+
"FBT",
|
|
150
|
+
"G",
|
|
151
|
+
"I",
|
|
152
|
+
"ICN",
|
|
153
|
+
"LOG",
|
|
154
|
+
"N",
|
|
155
|
+
"NPY",
|
|
156
|
+
"PD",
|
|
157
|
+
"PERF",
|
|
158
|
+
"PIE",
|
|
159
|
+
"PLE",
|
|
160
|
+
"PT",
|
|
161
|
+
"PTH",
|
|
162
|
+
"RUF",
|
|
163
|
+
"S",
|
|
164
|
+
"SIM",
|
|
165
|
+
"TC",
|
|
166
|
+
"TID",
|
|
167
|
+
"T100",
|
|
168
|
+
"YTT",
|
|
169
|
+
"UP",
|
|
170
|
+
"W",
|
|
171
|
+
]
|
|
172
|
+
fixable = ["ALL"]
|
|
173
|
+
unfixable = []
|
|
174
|
+
dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$"
|
|
175
|
+
|
|
176
|
+
[tool.ruff.lint.mccabe]
|
|
177
|
+
max-complexity = 18
|
|
178
|
+
|
|
179
|
+
[tool.ruff.lint.per-file-ignores]
|
|
180
|
+
"**/configs/**.py" = [
|
|
181
|
+
"F401",
|
|
182
|
+
"E402",
|
|
183
|
+
]
|
|
184
|
+
"**/__init__.py" = [
|
|
185
|
+
"F401",
|
|
186
|
+
"F403",
|
|
187
|
+
"E402",
|
|
188
|
+
]
|
|
189
|
+
"**/tests/config/**.py" = [
|
|
190
|
+
"F401",
|
|
191
|
+
"E402",
|
|
192
|
+
]
|
|
193
|
+
"**/tests/**.py" = [
|
|
194
|
+
"ANN",
|
|
195
|
+
"D100",
|
|
196
|
+
"D103",
|
|
197
|
+
"D104",
|
|
198
|
+
"S101",
|
|
199
|
+
]
|
|
200
|
+
|
|
201
|
+
[tool.ruff.lint.pydocstyle]
|
|
202
|
+
convention = "google"
|
|
203
|
+
|
|
204
|
+
[tool.ruff.lint.isort]
|
|
205
|
+
known-first-party = ["splitiq"]
|
|
206
|
+
known-third-party = [
|
|
207
|
+
"numpy",
|
|
208
|
+
"pandas",
|
|
209
|
+
"juliacall",
|
|
210
|
+
"juliapkg",
|
|
211
|
+
]
|
|
212
|
+
|
|
213
|
+
[tool.ruff.format]
|
|
214
|
+
quote-style = "single"
|
|
215
|
+
indent-style = "space"
|
|
216
|
+
skip-magic-trailing-comma = false
|
|
217
|
+
line-ending = "auto"
|
|
218
|
+
docstring-code-format = false
|
|
219
|
+
docstring-code-line-length = "dynamic"
|
|
220
|
+
|
|
221
|
+
[tool.pytest.ini_options]
|
|
222
|
+
minversion = "8.0"
|
|
223
|
+
testpaths = ["tests"]
|
|
224
|
+
pythonpath = ["src"]
|
|
225
|
+
python_files = ["test_*.py"]
|
|
226
|
+
norecursedirs = [
|
|
227
|
+
"hooks",
|
|
228
|
+
"*.egg",
|
|
229
|
+
".eggs",
|
|
230
|
+
"dist",
|
|
231
|
+
"build",
|
|
232
|
+
"docs",
|
|
233
|
+
".tox",
|
|
234
|
+
".git",
|
|
235
|
+
"__pycache__",
|
|
236
|
+
]
|
|
237
|
+
log_cli = "true"
|
|
238
|
+
markers = ["slow"]
|
|
239
|
+
doctest_optionflags = [
|
|
240
|
+
"NUMBER",
|
|
241
|
+
"NORMALIZE_WHITESPACE",
|
|
242
|
+
"IGNORE_EXCEPTION_DETAIL",
|
|
243
|
+
]
|
|
244
|
+
addopts = [
|
|
245
|
+
"--strict-markers",
|
|
246
|
+
"--tb=short",
|
|
247
|
+
"--doctest-modules",
|
|
248
|
+
"--doctest-continue-on-failure",
|
|
249
|
+
]
|
|
250
|
+
filterwarnings = [
|
|
251
|
+
"ignore::DeprecationWarning",
|
|
252
|
+
"ignore::UserWarning",
|
|
253
|
+
]
|
|
254
|
+
|
|
255
|
+
[tool.coverage.run]
|
|
256
|
+
source = ["src"]
|
|
257
|
+
branch = true
|
|
258
|
+
|
|
259
|
+
[tool.coverage.report]
|
|
260
|
+
fail_under = 50
|
|
261
|
+
show_missing = true
|