tabdgp 0.0.1__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.
- tabdgp-0.0.1/.github/workflows/ci.yml +24 -0
- tabdgp-0.0.1/.gitignore +12 -0
- tabdgp-0.0.1/CONTEXT.md +99 -0
- tabdgp-0.0.1/CONTRIBUTING.md +63 -0
- tabdgp-0.0.1/LICENSE +21 -0
- tabdgp-0.0.1/PKG-INFO +76 -0
- tabdgp-0.0.1/README.md +58 -0
- tabdgp-0.0.1/ROADMAP.md +19 -0
- tabdgp-0.0.1/docs/adr/.gitkeep +0 -0
- tabdgp-0.0.1/docs/adr/0001-one-dataset-per-draw-keyed-in-numpy.md +79 -0
- tabdgp-0.0.1/docs/conventions.md +164 -0
- tabdgp-0.0.1/docs/prior-art.md +65 -0
- tabdgp-0.0.1/lab/README.md +7 -0
- tabdgp-0.0.1/pyproject.toml +49 -0
- tabdgp-0.0.1/src/tabdgp/__init__.py +3 -0
- tabdgp-0.0.1/tests/test_readme.py +14 -0
- tabdgp-0.0.1/uv.lock +181 -0
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# Format check and the fast tests on three operating systems; the slow proofs run by hand or
|
|
2
|
+
# on the cluster (`uv run pytest -m slow`).
|
|
3
|
+
name: CI
|
|
4
|
+
|
|
5
|
+
on:
|
|
6
|
+
push:
|
|
7
|
+
branches: [main]
|
|
8
|
+
pull_request:
|
|
9
|
+
|
|
10
|
+
jobs:
|
|
11
|
+
test:
|
|
12
|
+
strategy:
|
|
13
|
+
fail-fast: false
|
|
14
|
+
matrix:
|
|
15
|
+
os: [ubuntu-latest, macos-latest, windows-latest]
|
|
16
|
+
runs-on: ${{ matrix.os }}
|
|
17
|
+
steps:
|
|
18
|
+
- uses: actions/checkout@v7
|
|
19
|
+
- uses: astral-sh/setup-uv@v10.2.0 # setup-uv publishes no major tag
|
|
20
|
+
with:
|
|
21
|
+
python-version: '3.14'
|
|
22
|
+
- run: uv sync
|
|
23
|
+
- run: uv run ruff format --check .
|
|
24
|
+
- run: uv run pytest -rs
|
tabdgp-0.0.1/.gitignore
ADDED
tabdgp-0.0.1/CONTEXT.md
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# TabDGP
|
|
2
|
+
|
|
3
|
+
A data-generating process for grouped and flat tables: what is drawn, how, and from which
|
|
4
|
+
distributions. Covariate generator, design matrix, within-group and group-level covariate,
|
|
5
|
+
group-confounded and quirk are metabeta's GLMM glossary's (`packages/mixed/CONTEXT.md` of
|
|
6
|
+
metabeta-v3) and are not redefined here; statistical terms (grouping factor, family, link)
|
|
7
|
+
too.
|
|
8
|
+
|
|
9
|
+
## Language
|
|
10
|
+
|
|
11
|
+
### The graph
|
|
12
|
+
|
|
13
|
+
**Node**:
|
|
14
|
+
One variable of a dataset's structural causal model (SCM): a grouping factor, a group-level or
|
|
15
|
+
within-group covariate, time, treatment, or the outcome node. A node has a parent set and a
|
|
16
|
+
mechanism; a node without parents is a root.
|
|
17
|
+
_Avoid_: feature, variable unqualified, unit (a neuron of an MLP)
|
|
18
|
+
|
|
19
|
+
**Mechanism**:
|
|
20
|
+
The function that computes a node's values from its parents' values and its own noise, drawn
|
|
21
|
+
per node from a mechanism family (linear, a small MLP, a tree). A root's mechanism is its noise.
|
|
22
|
+
_Avoid_: layer, activation (one part of it), edge function
|
|
23
|
+
|
|
24
|
+
**Generating graph**:
|
|
25
|
+
The directed acyclic graph of a dataset's nodes and their parent sets, returned with every
|
|
26
|
+
dataset.
|
|
27
|
+
_Avoid_: causal graph unqualified, DAG (one property of it), architecture
|
|
28
|
+
|
|
29
|
+
**Latent node**:
|
|
30
|
+
A node of the generating graph that is not a column of the table, kept in the output so that
|
|
31
|
+
the dataset stays white-box.
|
|
32
|
+
_Avoid_: hidden unit, confounder (a role a latent node can play)
|
|
33
|
+
|
|
34
|
+
**Column**:
|
|
35
|
+
A node observed in the table, with its metadata: type (continuous, binary, categorical,
|
|
36
|
+
ordered), levels, and role (grouping factor, covariate, time, treatment, outcome).
|
|
37
|
+
_Avoid_: feature, variable unqualified
|
|
38
|
+
|
|
39
|
+
**Marginal**:
|
|
40
|
+
The distribution a continuous column's values are mapped onto after the SCM, from a catalogue
|
|
41
|
+
of families (skewed, heavy-tailed, bounded, zero-inflated), keeping their ranks.
|
|
42
|
+
_Avoid_: noise distribution (the root's), prior
|
|
43
|
+
|
|
44
|
+
**Post-hoc type**:
|
|
45
|
+
The column type a continuous node is turned into after the SCM, by thresholds or bins on its
|
|
46
|
+
values: binary, categorical, ordered.
|
|
47
|
+
_Avoid_: dtype, encoding (the design matrix's)
|
|
48
|
+
|
|
49
|
+
### The draw
|
|
50
|
+
|
|
51
|
+
**Draw**:
|
|
52
|
+
The one public call: given a key and a hyperprior, one dataset, a pure function of both. Who
|
|
53
|
+
draws many loops over indices.
|
|
54
|
+
_Avoid_: sample (a row or a value), generate, batch
|
|
55
|
+
|
|
56
|
+
**Key**:
|
|
57
|
+
A seed and an index, the identity of one dataset: the same key, hyperprior and TabDGP version
|
|
58
|
+
give the same dataset bitwise, whatever the batch, worker or shard it is drawn in.
|
|
59
|
+
_Avoid_: rng, random state, seed alone
|
|
60
|
+
|
|
61
|
+
**Dataset**:
|
|
62
|
+
What a draw returns: the columns as named arrays in their natural dtype, their metadata, the
|
|
63
|
+
generating graph, the latent nodes' values, the hyperparameters every field resolved to, and
|
|
64
|
+
the key. Never padded, never a file.
|
|
65
|
+
_Avoid_: batch, table (the columns alone), sample, corpus (the consumer's set of keys)
|
|
66
|
+
|
|
67
|
+
**Hyperprior**:
|
|
68
|
+
The one config of distributions from which every quantity of a dataset is drawn: sizes,
|
|
69
|
+
graph, mechanisms, marginals, types, quirks. Its defaults are matched to mixedbench's registry
|
|
70
|
+
and then widened; they are what the proofs certify.
|
|
71
|
+
_Avoid_: prior (the fitter's, over parameters), config unqualified, meta-distribution
|
|
72
|
+
|
|
73
|
+
**Override**:
|
|
74
|
+
A point value or a distribution passed for one field of the hyperprior, replacing its default
|
|
75
|
+
for that call. A standalone user passes none; metabeta passes its sizes.
|
|
76
|
+
_Avoid_: setting, parameter, hyperparameter
|
|
77
|
+
|
|
78
|
+
**Quirk axis**:
|
|
79
|
+
One field of the hyperprior that controls one quirk of the catalogue, granted only when
|
|
80
|
+
mixedbench's measurement pass shows that real tables have the quirk strongly enough.
|
|
81
|
+
_Avoid_: noise, perturbation, augmentation
|
|
82
|
+
|
|
83
|
+
**Outcome node**:
|
|
84
|
+
An optional node whose parents are drawn from the covariates, with a family, a link and terms
|
|
85
|
+
a GLMM lacks, that builds white-box misspecified datasets. Just another node; never drawn
|
|
86
|
+
unless asked for.
|
|
87
|
+
_Avoid_: y, target, label, response unqualified
|
|
88
|
+
|
|
89
|
+
### The proofs
|
|
90
|
+
|
|
91
|
+
**Two-sample test**:
|
|
92
|
+
A classifier two-sample test (C2ST) on the summary vector of generated and registry tables:
|
|
93
|
+
the defaults pass when its accuracy stays below the bar.
|
|
94
|
+
_Avoid_: discriminator, realism score
|
|
95
|
+
|
|
96
|
+
**Containment test**:
|
|
97
|
+
The test that every registry row's summary vector lies inside the support of the generated
|
|
98
|
+
ones.
|
|
99
|
+
_Avoid_: coverage (the fitter's credible-interval property)
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# Contributing to TabDGP
|
|
2
|
+
|
|
3
|
+
Thank you for your interest. TabDGP is early stage and help is welcome.
|
|
4
|
+
|
|
5
|
+
## Ways to help
|
|
6
|
+
|
|
7
|
+
- **A real-data quirk the generator misses.** Open an issue naming the property, a public
|
|
8
|
+
table that shows it and, if you can, how to measure it per column or per grouping factor;
|
|
9
|
+
the quirk catalogue grows through the measurement pass, never by hand.
|
|
10
|
+
- **A bug in a mechanism or a proof.** Open an issue with the smallest example that shows it,
|
|
11
|
+
or a pull request with a failing test and the fix.
|
|
12
|
+
- **A use case.** A model family or a simulation study that needs something the hyperprior
|
|
13
|
+
cannot express: open an issue describing the dataset you cannot draw.
|
|
14
|
+
|
|
15
|
+
For anything bigger than a small fix, open an issue before writing code, so we can agree on
|
|
16
|
+
the approach first.
|
|
17
|
+
|
|
18
|
+
## Set up
|
|
19
|
+
|
|
20
|
+
You need [uv](https://docs.astral.sh/uv/).
|
|
21
|
+
|
|
22
|
+
```
|
|
23
|
+
git clone https://github.com/adkipnis/tabdgp
|
|
24
|
+
cd tabdgp
|
|
25
|
+
uv sync
|
|
26
|
+
uv run pytest # the fast tests
|
|
27
|
+
uv run pytest -m slow # the proofs against mixedbench's registry
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Find your way
|
|
31
|
+
|
|
32
|
+
```
|
|
33
|
+
src/tabdgp/ the package; each module's docstring says what it defines and how
|
|
34
|
+
tests/ mirrors src/, fixtures beside the tests
|
|
35
|
+
docs/adr/ the design decisions and why they were taken
|
|
36
|
+
docs/ the conventions and the proofs' method
|
|
37
|
+
lab/ one notebook per small design choice, indexed in lab/README.md
|
|
38
|
+
examples/ the demo notebook
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
[`CONTEXT.md`](CONTEXT.md) defines the words (node, mechanism, hyperprior, override, quirk
|
|
42
|
+
axis, outcome node); the covariate terms are metabeta's GLMM glossary's.
|
|
43
|
+
|
|
44
|
+
## Pull requests
|
|
45
|
+
|
|
46
|
+
- Branch off `main`, one change per pull request, linked to its issue.
|
|
47
|
+
- Add a test with each change; mark a test that draws thousands of datasets `slow`.
|
|
48
|
+
- Run `uv run ruff format .` and `uv run pytest`. CI runs both.
|
|
49
|
+
- Please follow the style [conventions](docs/conventions.md).
|
|
50
|
+
|
|
51
|
+
Three rules keep the generator trustworthy:
|
|
52
|
+
|
|
53
|
+
- **The defaults are what the proofs certify.** A change to a default distribution of the
|
|
54
|
+
hyperprior, to a proof's seed or to its bar is discussed in an issue first and recorded in
|
|
55
|
+
the changelog; downstream training corpora depend on them.
|
|
56
|
+
- **Written from scratch.** scamd and TabICL's prior are read for ideas; no code is copied
|
|
57
|
+
from either. A mechanism they inspired says so in a comment.
|
|
58
|
+
- **Nothing from downstream.** TabDGP imports nothing from metabeta or mixedbench; the proofs
|
|
59
|
+
read mixedbench's registry as a test dependency only.
|
|
60
|
+
|
|
61
|
+
## Licence
|
|
62
|
+
|
|
63
|
+
By contributing, you agree that your changes are released under [MIT](LICENSE).
|
tabdgp-0.0.1/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Alex Kipnis
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
tabdgp-0.0.1/PKG-INFO
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: tabdgp
|
|
3
|
+
Version: 0.0.1
|
|
4
|
+
Summary: A data-generating process for grouped and flat tables, matched to a registry of real tables
|
|
5
|
+
Project-URL: Repository, https://github.com/adkipnis/tabdgp
|
|
6
|
+
Project-URL: Issues, https://github.com/adkipnis/tabdgp/issues
|
|
7
|
+
Project-URL: Roadmap, https://github.com/adkipnis/tabdgp/blob/main/ROADMAP.md
|
|
8
|
+
Author-email: Alex Kipnis <adkipnis@users.noreply.github.com>
|
|
9
|
+
License-Expression: MIT
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Classifier: Development Status :: 1 - Planning
|
|
12
|
+
Classifier: Intended Audience :: Science/Research
|
|
13
|
+
Classifier: Operating System :: OS Independent
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
15
|
+
Classifier: Topic :: Scientific/Engineering
|
|
16
|
+
Requires-Python: >=3.14
|
|
17
|
+
Description-Content-Type: text/markdown
|
|
18
|
+
|
|
19
|
+
[](https://github.com/adkipnis/tabdgp/actions/workflows/ci.yml)
|
|
20
|
+
[](https://github.com/adkipnis/tabdgp/blob/main/LICENSE)
|
|
21
|
+
|
|
22
|
+
# TabDGP
|
|
23
|
+
|
|
24
|
+
A data-generating process (DGP) for grouped and flat tables: grouping structure and typed
|
|
25
|
+
covariates with the quirks of real data.
|
|
26
|
+
|
|
27
|
+
## What and why
|
|
28
|
+
|
|
29
|
+
- **Measured against real tables.** The default hyperprior is matched to
|
|
30
|
+
[mixedbench](https://github.com/adkipnis/mixedbench)'s registry of real grouped tables, then
|
|
31
|
+
widened; two tests prove it: generated tables are indistinguishable from real ones on their
|
|
32
|
+
summary statistics, and every real table lies inside the generated support.
|
|
33
|
+
- **White-box.** Every dataset comes with its generating graph, its latent nodes and its column
|
|
34
|
+
metadata (type, levels, role).
|
|
35
|
+
- **Composable.** One structural causal model whose nodes are grouping factors, group-level and
|
|
36
|
+
within-group covariates, time and treatment; a flat table is the case without grouping
|
|
37
|
+
factors.
|
|
38
|
+
- **The quirks i.i.d. simulators lack.** Group confounding, empty cells, rare levels, ties,
|
|
39
|
+
bounds, irregular time, near dependence, leverage points: a catalogue, each quirk measured on
|
|
40
|
+
real tables before it gets an axis.
|
|
41
|
+
- **Covariates only.** The outcome belongs to whoever fits a model; an optional outcome node
|
|
42
|
+
builds white-box misspecified datasets.
|
|
43
|
+
- **Overridable.** Every quantity has a default distribution; pass a point value or another
|
|
44
|
+
distribution for any of them.
|
|
45
|
+
|
|
46
|
+
## Install
|
|
47
|
+
|
|
48
|
+
```
|
|
49
|
+
pip install tabdgp
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
From source:
|
|
53
|
+
|
|
54
|
+
```
|
|
55
|
+
git clone https://github.com/adkipnis/tabdgp
|
|
56
|
+
cd tabdgp
|
|
57
|
+
uv sync
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Quickstart
|
|
61
|
+
|
|
62
|
+
The first call arrives with roadmap item 1; see [`ROADMAP.md`](https://github.com/adkipnis/tabdgp/blob/main/ROADMAP.md).
|
|
63
|
+
|
|
64
|
+
## Contents
|
|
65
|
+
|
|
66
|
+
- The package `tabdgp` under `src/`.
|
|
67
|
+
- [`CONTEXT.md`](https://github.com/adkipnis/tabdgp/blob/main/CONTEXT.md): the vocabulary;
|
|
68
|
+
[`docs/adr/`](https://github.com/adkipnis/tabdgp/tree/main/docs/adr): the design decisions.
|
|
69
|
+
|
|
70
|
+
## Contributing
|
|
71
|
+
|
|
72
|
+
Interested in becoming part of TabDGP? Check out [`CONTRIBUTING.md`](https://github.com/adkipnis/tabdgp/blob/main/CONTRIBUTING.md).
|
|
73
|
+
|
|
74
|
+
## Licence
|
|
75
|
+
|
|
76
|
+
[MIT](https://github.com/adkipnis/tabdgp/blob/main/LICENSE).
|
tabdgp-0.0.1/README.md
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
[](https://github.com/adkipnis/tabdgp/actions/workflows/ci.yml)
|
|
2
|
+
[](https://github.com/adkipnis/tabdgp/blob/main/LICENSE)
|
|
3
|
+
|
|
4
|
+
# TabDGP
|
|
5
|
+
|
|
6
|
+
A data-generating process (DGP) for grouped and flat tables: grouping structure and typed
|
|
7
|
+
covariates with the quirks of real data.
|
|
8
|
+
|
|
9
|
+
## What and why
|
|
10
|
+
|
|
11
|
+
- **Measured against real tables.** The default hyperprior is matched to
|
|
12
|
+
[mixedbench](https://github.com/adkipnis/mixedbench)'s registry of real grouped tables, then
|
|
13
|
+
widened; two tests prove it: generated tables are indistinguishable from real ones on their
|
|
14
|
+
summary statistics, and every real table lies inside the generated support.
|
|
15
|
+
- **White-box.** Every dataset comes with its generating graph, its latent nodes and its column
|
|
16
|
+
metadata (type, levels, role).
|
|
17
|
+
- **Composable.** One structural causal model whose nodes are grouping factors, group-level and
|
|
18
|
+
within-group covariates, time and treatment; a flat table is the case without grouping
|
|
19
|
+
factors.
|
|
20
|
+
- **The quirks i.i.d. simulators lack.** Group confounding, empty cells, rare levels, ties,
|
|
21
|
+
bounds, irregular time, near dependence, leverage points: a catalogue, each quirk measured on
|
|
22
|
+
real tables before it gets an axis.
|
|
23
|
+
- **Covariates only.** The outcome belongs to whoever fits a model; an optional outcome node
|
|
24
|
+
builds white-box misspecified datasets.
|
|
25
|
+
- **Overridable.** Every quantity has a default distribution; pass a point value or another
|
|
26
|
+
distribution for any of them.
|
|
27
|
+
|
|
28
|
+
## Install
|
|
29
|
+
|
|
30
|
+
```
|
|
31
|
+
pip install tabdgp
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
From source:
|
|
35
|
+
|
|
36
|
+
```
|
|
37
|
+
git clone https://github.com/adkipnis/tabdgp
|
|
38
|
+
cd tabdgp
|
|
39
|
+
uv sync
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Quickstart
|
|
43
|
+
|
|
44
|
+
The first call arrives with roadmap item 1; see [`ROADMAP.md`](https://github.com/adkipnis/tabdgp/blob/main/ROADMAP.md).
|
|
45
|
+
|
|
46
|
+
## Contents
|
|
47
|
+
|
|
48
|
+
- The package `tabdgp` under `src/`.
|
|
49
|
+
- [`CONTEXT.md`](https://github.com/adkipnis/tabdgp/blob/main/CONTEXT.md): the vocabulary;
|
|
50
|
+
[`docs/adr/`](https://github.com/adkipnis/tabdgp/tree/main/docs/adr): the design decisions.
|
|
51
|
+
|
|
52
|
+
## Contributing
|
|
53
|
+
|
|
54
|
+
Interested in becoming part of TabDGP? Check out [`CONTRIBUTING.md`](https://github.com/adkipnis/tabdgp/blob/main/CONTRIBUTING.md).
|
|
55
|
+
|
|
56
|
+
## Licence
|
|
57
|
+
|
|
58
|
+
[MIT](https://github.com/adkipnis/tabdgp/blob/main/LICENSE).
|
tabdgp-0.0.1/ROADMAP.md
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# TabDGP — Roadmap
|
|
2
|
+
|
|
3
|
+
Decided in metabeta-v3's Phase 1 grill (2026-10-11; its root ADR 0005 and
|
|
4
|
+
`packages/mixed` ADR 0005), moved here from metabeta-v3's `ROADMAP.md` when the repository
|
|
5
|
+
was created. Order reflects dependencies. Specs and tickets are GitHub Issues on this
|
|
6
|
+
repository.
|
|
7
|
+
|
|
8
|
+
- [ ] **1 The flat SCM.** The repository on mixedbench's template; the flat structural causal
|
|
9
|
+
model with a marginal catalogue and typed post-hoc columns, written from scratch with scamd
|
|
10
|
+
and TabICL's prior read for ideas; the hyperprior config with overrides; tests; the tensor
|
|
11
|
+
library decided in this spec
|
|
12
|
+
- [ ] **2 Grouping nodes.** Group-level and within-group covariates, the imbalance draw of
|
|
13
|
+
metabeta's envelope rule 7, within-group time, binary treatment; metabeta.mixed's slice A1
|
|
14
|
+
starts after this
|
|
15
|
+
- [ ] **3 Measurement pass and proofs.** The measurement pass over mixedbench's cached tables
|
|
16
|
+
(a mixedbench issue: the quirk statistics per column and per factor) and the two proof
|
|
17
|
+
tests, the two-sample test and the containment test
|
|
18
|
+
- [ ] **4 Quirk axes.** The quirk axes the pass justifies and the matched, widened hyperprior
|
|
19
|
+
- [ ] **5 Outcome node.** The optional outcome node for white-box misspecified datasets
|
|
File without changes
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
---
|
|
2
|
+
status: accepted
|
|
3
|
+
date: 2026-10-11
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# 0001 — One dataset per draw, keyed by seed and index, in numpy
|
|
7
|
+
|
|
8
|
+
TabDGP's first consumer, `metabeta.mixed`, trains on simulated datasets whose sizes, groups
|
|
9
|
+
and columns all vary; its roadmap puts padding, masking, collate and the `.npz` corpus on
|
|
10
|
+
`metabeta.core`, and its Simulator adds the outcome before anything is written. Grilled on
|
|
11
|
+
2026-10-11 (storage, batch layout, tensor library, item 1 of `ROADMAP.md`), the decision is:
|
|
12
|
+
**the seed is the corpus.** Dataset `i` is a pure function of its key `(seed, index)`, the
|
|
13
|
+
hyperprior with its overrides and the installed TabDGP version. The public call draws one
|
|
14
|
+
dataset, `draw(seed, index, hyperprior) -> Dataset`, in numpy, at the dataset's own shapes.
|
|
15
|
+
TabDGP never pads, never batches across datasets and never writes a file.
|
|
16
|
+
|
|
17
|
+
## Considered options
|
|
18
|
+
|
|
19
|
+
- **Online generation or a stored corpus.** A stored corpus buys reproducibility and a frozen
|
|
20
|
+
schema at the cost of disk, plumbing and an incompatibility that stays hidden until the next
|
|
21
|
+
regeneration. With a deterministic generator the two are the same data: a consumer
|
|
22
|
+
generates per epoch from `(seed, index)`, keeps variety by changing the seed and snapshots
|
|
23
|
+
only what carries expensive references (its validation and test sets). Trimming stored full
|
|
24
|
+
tables was rejected: subsampling rows breaks the imbalance draw and the group-level
|
|
25
|
+
structure, and a draw at the needed size is cheap.
|
|
26
|
+
- **Determinism per dataset or per batch.** Per batch, `(seed, batch)`, is cheaper but gives a
|
|
27
|
+
dataset no identity outside its batch, so bucketing by size or resharding changes the data.
|
|
28
|
+
Per dataset, bitwise on CPU whatever the batch, worker or shard, is what a virtual corpus
|
|
29
|
+
needs. Bitwise identity across devices is not promised: it is a promise no library keeps
|
|
30
|
+
across versions, and the draw runs on CPU.
|
|
31
|
+
- **Batch layout: a loop over datasets, or one padded batch.** Datasets in a batch differ in
|
|
32
|
+
rows, columns, groups and in their generating graph (node count, edges, mechanism per node,
|
|
33
|
+
marginals, post-hoc types), so a padded batch means masks through every mechanism and a
|
|
34
|
+
padded adjacency, TabICL's road, which TabICL itself left. A padded batch also breaks
|
|
35
|
+
per-dataset determinism on a GPU, where matrix kernels are chosen by shape. A loop over
|
|
36
|
+
datasets, each vectorised over its own rows, groups and columns, has no masks and no way for
|
|
37
|
+
dataset `i` to depend on its neighbours. GPU generation was weighed and rejected for the
|
|
38
|
+
same reason: a dataset of about 2,000 rows by 20 columns is launch-bound, scatter and
|
|
39
|
+
index-add (group aggregations) are non-deterministic on CUDA by default, and a GPU node's
|
|
40
|
+
idle CPU cores draw in parallel instead.
|
|
41
|
+
- **Tensor library.** JAX's `vmap` and `jit` are what this layout does not use, and shapes
|
|
42
|
+
that differ per dataset leave it eager and slow. torch buys metabeta's stack at the cost of a
|
|
43
|
+
heavy dependency on every standalone user, a keyed sampler catalogue to maintain (its
|
|
44
|
+
`distributions` take no generator except `Gamma`), and five to ten times numpy's
|
|
45
|
+
per-operation overhead on small CPU arrays. numpy's `Generator` is a complete keyed
|
|
46
|
+
catalogue, `default_rng([seed, index])` is the key, dynamic shapes are free, and metabeta's
|
|
47
|
+
tensors are `torch.from_numpy`, zero copy. scipy may be added when it supplies a sampler
|
|
48
|
+
numpy lacks.
|
|
49
|
+
- **Public call: a batch or a dataset.** A stateful generator argument makes dataset 256
|
|
50
|
+
depend on how much randomness datasets 0 to 255 consumed, so the key must be in the
|
|
51
|
+
signature. A `Batch` indexable to a `Dataset` is a list comprehension the caller writes as
|
|
52
|
+
well as we do, and the consumer that buckets by size calls per dataset anyway, with its
|
|
53
|
+
sizes as point overrides on a copied hyperprior.
|
|
54
|
+
- **Container: named arrays or one matrix.** One `(N, p)` float matrix stores categoricals and
|
|
55
|
+
group indices as floats, and both consumers derive what they need from the metadata anyway.
|
|
56
|
+
`Dataset` holds the columns as named one-dimensional arrays in their natural dtype, the
|
|
57
|
+
column metadata, the generating graph with every node including the latent ones, the latent
|
|
58
|
+
nodes' values, the hyperparameters every field resolved to, and the key.
|
|
59
|
+
|
|
60
|
+
## Consequences
|
|
61
|
+
|
|
62
|
+
- One public function, one container, no batch object, no storage code, no padding code and
|
|
63
|
+
no parallelism inside TabDGP: a draw is a pure function of its key, so a process pool over
|
|
64
|
+
indices is the caller's one line, and nesting a pool inside a consumer's dataloader workers
|
|
65
|
+
would be wrong.
|
|
66
|
+
- The end-to-end test draws dataset `i` alone and inside two different index sets and asserts
|
|
67
|
+
bitwise equality; the proofs draw their fixed-seed datasets by index and store nothing.
|
|
68
|
+
- The hyperprior and its resolution share one Pydantic type: an override is a point value or
|
|
69
|
+
a distribution on a field, a resolved hyperparameter a point value on the same field.
|
|
70
|
+
- Throughput is a bar, not a hope: the spec's first ticket is a lab note timing the core draw
|
|
71
|
+
(graph, MLP propagation, one rank-matched marginal, one binary threshold) on one core at
|
|
72
|
+
N in {100, 1k, 10k} and the scaling of a process pool over indices. If the core draw falls
|
|
73
|
+
under about 500 datasets per second per core at the mean v1 size, a padded torch batch
|
|
74
|
+
behind the same one-dataset interface is the fallback.
|
|
75
|
+
- A DataFrame is `pandas.DataFrame(dataset.columns)` and needs no dependency here.
|
|
76
|
+
- For `metabeta.mixed`'s slice A1: generate per epoch from `(seed, index)` in dataloader
|
|
77
|
+
workers, pin TabDGP, snapshot validation and test sets, draw an epoch's sizes first (its
|
|
78
|
+
envelope rule 8) and bucket by them before drawing contents, and keep a contract test on the
|
|
79
|
+
schema at the boundary. These are its decisions to record.
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
# Conventions
|
|
2
|
+
|
|
3
|
+
The rules a change is reviewed against. The words are [`CONTEXT.md`](../CONTEXT.md)'s; the
|
|
4
|
+
reasons behind the larger rules are in the [ADRs](adr).
|
|
5
|
+
|
|
6
|
+
## Tooling
|
|
7
|
+
|
|
8
|
+
- Python 3.14 through `uv` only; `uv run` for everything, every command from the repository
|
|
9
|
+
root, without `cd`.
|
|
10
|
+
- `ruff format` and `pytest`, run by CI.
|
|
11
|
+
- Open an issue before adding a heavyweight dependency.
|
|
12
|
+
|
|
13
|
+
## Modules
|
|
14
|
+
|
|
15
|
+
Each module owns one design decision that no other module depends on. The table fills as the
|
|
16
|
+
modules arrive:
|
|
17
|
+
|
|
18
|
+
| module | owns | imported by |
|
|
19
|
+
|---|---|---|
|
|
20
|
+
|
|
21
|
+
## Design
|
|
22
|
+
|
|
23
|
+
After Ousterhout, *A Philosophy of Software Design*: complexity is anything that makes code
|
|
24
|
+
harder to understand or change; it accrues one small edit at a time.
|
|
25
|
+
|
|
26
|
+
- **Deep modules.** A small interface over much functionality; an interface as complex as its
|
|
27
|
+
implementation folds into its caller or callee.
|
|
28
|
+
- **Information hiding.** Each module owns one design decision (a node mechanism, a tensor
|
|
29
|
+
layout, the hyperprior's parameterisation). Split code by what it knows, not by the order
|
|
30
|
+
it runs in.
|
|
31
|
+
- **No pass-throughs.** A method that forwards its arguments unchanged adds nothing; call the
|
|
32
|
+
target directly.
|
|
33
|
+
- **Pull complexity down.** The module absorbs the awkward case so its callers stay simple. A
|
|
34
|
+
fixed sensible behaviour beats a new config parameter.
|
|
35
|
+
- **Define errors out of existence.** Shape the interface so the invalid case cannot arise
|
|
36
|
+
(accept the empty set, validate once at construction). The rest fails loudly: no fallbacks,
|
|
37
|
+
no defensive `try`/`except`, no speculative generality. Branch only for cases observed on
|
|
38
|
+
real inputs; add the next branch when use hits it.
|
|
39
|
+
- **Design it twice.** For a non-trivial interface, name two designs and why one wins before
|
|
40
|
+
writing code.
|
|
41
|
+
- **Obvious over clever.** The simplest form a reader guesses right on first read, in code
|
|
42
|
+
written, reviewed or rewritten. If 200 lines could be 50, rewrite them.
|
|
43
|
+
|
|
44
|
+
## Changing code
|
|
45
|
+
|
|
46
|
+
- The smallest change that solves the problem and meets the design bar, no unrequested
|
|
47
|
+
extras. Leave adjacent code, comments and formatting untouched.
|
|
48
|
+
- Written from scratch: scamd and TabICL's prior are read for ideas, never copied. A mechanism
|
|
49
|
+
one of them inspired names it in a comment. Where a formula comes from a paper, the comment
|
|
50
|
+
cites it (a link, an equation number).
|
|
51
|
+
- A task that repeats, or is error-prone by hand, gets a `.py` or `.sh` script.
|
|
52
|
+
|
|
53
|
+
## Names
|
|
54
|
+
|
|
55
|
+
- A module is one lowercase word. A package's `__init__.py` lists its public names in
|
|
56
|
+
`__all__`.
|
|
57
|
+
- `PascalCase` for classes and `Literal` aliases, `camelCase` for functions and methods,
|
|
58
|
+
`snake_case` for variables, `UPPER_SNAKE_CASE` for constants.
|
|
59
|
+
- A directory is `dir`, not `folder`. A DataFrame is a `table`, several are `tables`, never
|
|
60
|
+
`df` or `frame`.
|
|
61
|
+
- A leading `_` marks a pipeline step and anything no other module imports.
|
|
62
|
+
- Tests live in `tests/`, mirroring `src/`, one `test_<module>.py` per module, each test named
|
|
63
|
+
as a sentence (`test_<what_holds>`), fixtures in a `fixtures/` beside them.
|
|
64
|
+
|
|
65
|
+
## Code
|
|
66
|
+
|
|
67
|
+
- Absolute imports: `from tabdgp.x import y`.
|
|
68
|
+
- Modern typing: `X | Y`, built-in generics, `from __future__ import annotations`.
|
|
69
|
+
`Literal[...]` for an argument with a fixed set of options, a type alias once it repeats.
|
|
70
|
+
Config models are Pydantic.
|
|
71
|
+
- f-strings, one statement per line, a long expression named on the line before.
|
|
72
|
+
- A method lists its steps in the order you would describe them; a step with its own `if`
|
|
73
|
+
ladder or loop becomes a method. A search is a plain loop with an explicit check after it,
|
|
74
|
+
not `for`/`else`, `while True` or `next()` on a generator.
|
|
75
|
+
- `a if c else b` only on a short line. Lookup tables are literal dicts or `if` chains, not
|
|
76
|
+
built with comprehensions, `dict.fromkeys` or `|`.
|
|
77
|
+
- A class per concept a reader should hold apart (a mechanism family, a pipeline), static
|
|
78
|
+
methods where it holds no state. A helper or constant used by one class lives on it; module
|
|
79
|
+
functions are for what spans classes.
|
|
80
|
+
- Wrap `argparse` blocks in `# fmt: off` / `# fmt: on`.
|
|
81
|
+
|
|
82
|
+
### Arrays and tensors
|
|
83
|
+
|
|
84
|
+
- Annotate shapes inline (`# (B, N, p)` for B datasets of N rows and p columns), reshape with
|
|
85
|
+
`einops` where the library has it, never mutate a reused array in place. Vectorise with
|
|
86
|
+
broadcasting and advanced indexing, not loops; batch over datasets.
|
|
87
|
+
- Every draw takes an explicit generator or key; nothing reads global random state.
|
|
88
|
+
|
|
89
|
+
## File layout
|
|
90
|
+
|
|
91
|
+
```python
|
|
92
|
+
"""grouping.py defines how a dataset's grouping factors and group sizes are drawn.
|
|
93
|
+
|
|
94
|
+
pipeline:
|
|
95
|
+
---------
|
|
96
|
+
the overrides and the hyperprior
|
|
97
|
+
-> the number of factors and their relation _factors
|
|
98
|
+
-> groups per factor and the group sizes _sizes
|
|
99
|
+
-> one assignment array per factor draw
|
|
100
|
+
"""
|
|
101
|
+
|
|
102
|
+
# =====================================================================================
|
|
103
|
+
# default hyperprior
|
|
104
|
+
# =====================================================================================
|
|
105
|
+
# the distributions every quantity falls back to when no override names one.
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
- The module docstring: one sentence on what the module defines, optionally a short paragraph
|
|
109
|
+
on how, then the pipeline, one `-> result` line per step with its function on the right.
|
|
110
|
+
Who imports the module is the [map](#modules)'s.
|
|
111
|
+
- `# ====` banners separate globals, classes and main, `# ----` banners subsections. Each is
|
|
112
|
+
named in plain words, with one comment line on why the section exists unless a class
|
|
113
|
+
docstring below says it.
|
|
114
|
+
- One pipeline class per module: public methods first, then its steps in run order under a
|
|
115
|
+
`# ----` banner naming the pipeline.
|
|
116
|
+
- A script's `__main__` creates its pipeline class and reads as the run's table of contents.
|
|
117
|
+
|
|
118
|
+
## Comments and docstrings
|
|
119
|
+
|
|
120
|
+
- Comments start in lower case; docstrings are capitalised sentences. Break the lines of both
|
|
121
|
+
at sentence or clause boundaries, not at the column limit.
|
|
122
|
+
- A docstring only where the behaviour or design is not obvious: one or two plain sentences,
|
|
123
|
+
none on a method its name and body already explain, never a chain of `;` clauses. Detail
|
|
124
|
+
goes into inline comments that say why and cite sources, and into trailing comments on
|
|
125
|
+
config fields.
|
|
126
|
+
- A comment explains the code, not its history: the case behind a rule goes to the test that
|
|
127
|
+
pins it, a definition to `CONTEXT.md`, how it was decided to an ADR or a lab note.
|
|
128
|
+
- Code in `src/` states its rules without citing an ADR; the ADR keeps the reason.
|
|
129
|
+
|
|
130
|
+
## Tests
|
|
131
|
+
|
|
132
|
+
- Test first: the failing test, then the minimal code. `hypothesis` for property tests.
|
|
133
|
+
- Unit tests for every mechanism: marginal ranges, the coded shapes, determinism under a
|
|
134
|
+
fixed generator, every override honoured, the flat case as zero factors.
|
|
135
|
+
- The proofs against mixedbench's registry (the two-sample test and the containment test)
|
|
136
|
+
carry the `slow` mark and fixed seeds.
|
|
137
|
+
- Each test says in a sentence or two why it exists, unless obvious. Bind the object under
|
|
138
|
+
test, then call it; small named helpers, not lambdas or repeated comprehensions.
|
|
139
|
+
- No coverage gate.
|
|
140
|
+
|
|
141
|
+
## Docs
|
|
142
|
+
|
|
143
|
+
Markdown meets the same bar as code: simple, and read top to bottom.
|
|
144
|
+
|
|
145
|
+
- Short bullets, the essentials first, detail in an appendix or a linked file.
|
|
146
|
+
- One home per fact, links everywhere else; a living rule sits with the method it governs.
|
|
147
|
+
Counts live in generated files, never in prose.
|
|
148
|
+
- `README.md` is for users and fits one screen: badges, a short what and why, install, one
|
|
149
|
+
quickstart box, contents, contributing, citing, licence. Its links are absolute to `main`,
|
|
150
|
+
so PyPI renders them.
|
|
151
|
+
|
|
152
|
+
## Data
|
|
153
|
+
|
|
154
|
+
- The registry statistics the proofs read are mixedbench's, pinned by version, never edited
|
|
155
|
+
here.
|
|
156
|
+
- Stream or lazily load data that would not fit in memory.
|
|
157
|
+
- Figures are PDFs, never rasterised.
|
|
158
|
+
|
|
159
|
+
## Lab notes and experiments
|
|
160
|
+
|
|
161
|
+
- `lab/YYYY-MM-DD-slug/`: one small design choice, its notebook committed with outputs and
|
|
162
|
+
indexed in `lab/README.md` with the decision. Never imported.
|
|
163
|
+
- `experiments/`: rerunnable scripted studies that feed a paper. Rerun with flags; never
|
|
164
|
+
one-off.
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# Prior art
|
|
2
|
+
|
|
3
|
+
What scamd (`~/Code/scamd`, the prototype) and TabICL's prior (`~/Code/tabicl/src/tabicl/prior/`,
|
|
4
|
+
BSD-3, read at commit c91f00d) do, read for ideas only: no code is copied, and a mechanism one
|
|
5
|
+
of them inspired names it in a comment. Read 2026-10-11.
|
|
6
|
+
|
|
7
|
+
## Shared by both
|
|
8
|
+
|
|
9
|
+
- PyTorch tensors, one dataset at a time: neither batches inside its SCM. TabICL batches by
|
|
10
|
+
padding features to a maximum and stacking, with a process pool over datasets.
|
|
11
|
+
- Both mix an explicit generator with global random state, so neither reproduces from one seed.
|
|
12
|
+
- Neither returns column types, the graph or the drawn hyperparameters.
|
|
13
|
+
|
|
14
|
+
## scamd
|
|
15
|
+
|
|
16
|
+
- **SCM**: an MLP whose hidden units are the nodes (weights redrawn on every pass, dense with
|
|
17
|
+
dropout or block-diagonal), or a DAG option (Barabási–Albert or Erdős–Rényi, one activation
|
|
18
|
+
for all nodes). Activations: about 25 elementwise functions and random-Fourier GP functions.
|
|
19
|
+
- **Marginal catalogue**, applied to the root causes: normal, uniform, multinomial index,
|
|
20
|
+
Zipf, gamma, lognormal, beta, Student-t, Gaussian mixture; after the SCM, a power or log1p
|
|
21
|
+
warp per column.
|
|
22
|
+
- **Post-hoc column types**: threshold (binary), multi-threshold and quantile bins (ordered),
|
|
23
|
+
softmax categoricals, an ordinal block over a shared direction, Poisson and negative
|
|
24
|
+
binomial counts, clamps and censored floors. Each post-hoc column mixes all SCM columns.
|
|
25
|
+
- **Correlation**: block-wise weights, a Gaussian copula on the causes, a factor layer, and
|
|
26
|
+
shared noise (one noise vector added to a group of columns).
|
|
27
|
+
- **Config**: plain dict presets; extra keyword arguments routed by `inspect.signature`.
|
|
28
|
+
- **Weaknesses**: noise calibrated once while weights are redrawn; absolute noise scales; a
|
|
29
|
+
`sanityCheck` that only rejects all-non-finite data; column position reveals type; levels
|
|
30
|
+
fixed at 3.
|
|
31
|
+
|
|
32
|
+
## TabICL
|
|
33
|
+
|
|
34
|
+
- **Hyperparameter meta-distributions**: a hyperparameter is drawn from a distribution whose
|
|
35
|
+
own parameters are drawn first (log-scaled truncated normal, Beta, choice over softmaxed
|
|
36
|
+
random logits). The parameters are drawn once per group of datasets, the values per dataset.
|
|
37
|
+
A spec entry is a constant or a distribution, recursively; defaults fill only what the user
|
|
38
|
+
left out.
|
|
39
|
+
- **Starting ranges**: layers 2 to about 8, hidden width about 9 to 134, init scale 0.01 to 10,
|
|
40
|
+
noise 1e-4 to 0.3, causes 2 to about 13, dropout 0.9·Beta, categorical share 0.2.
|
|
41
|
+
- **Graph SCM** (`graph_lib`): a Cauchy DAG, where an edge i→j (i < j) exists with probability
|
|
42
|
+
σ(offset + out_j + in_i) with Cauchy draws, so density ranges from near-empty to
|
|
43
|
+
near-complete and hubs arise. Node count 2–32, log scale. Vector-valued nodes; roots are base
|
|
44
|
+
points through a random function; parents are concatenated or combined by sum, product, max
|
|
45
|
+
or logsumexp. Function families: MLP, oblivious trees, nearest-centre discretisation, linear,
|
|
46
|
+
quadratic, random-Fourier GP, softmax, products.
|
|
47
|
+
- **Named draws** through one sampler with a mode per name: `global` (one value), `meta` (a
|
|
48
|
+
per-dataset Beta that correlates repeated draws of a name within a dataset), `local` (i.i.d.);
|
|
49
|
+
`boundary_mass` puts mass at the ends of an interval (all numeric, all categorical).
|
|
50
|
+
- **Categoricals**: k − 1 thresholds at random sample values with labels permuted (v1);
|
|
51
|
+
nearest-centre or softmax converters (graph SCM). Numeric columns get a Kumaraswamy warp.
|
|
52
|
+
- **Not taken over**: y as a node of the SCM, and the two-pass 4σ outlier clipping with z-scores
|
|
53
|
+
clipped to ±100.
|
|
54
|
+
|
|
55
|
+
## Ideas carried into TabDGP's design (proposed, not yet decided)
|
|
56
|
+
|
|
57
|
+
- A recursive point-or-distribution field: for a per-column field, its distribution's
|
|
58
|
+
parameters drawn once per dataset and its values once per column (TabICL's meta draws), so
|
|
59
|
+
that corners such as an all-binary table get mass.
|
|
60
|
+
- The Cauchy DAG for edge density (TabICL); scamd's shared noise and block-wise correlation as
|
|
61
|
+
latent hub nodes and a within-block edge bonus in the graph draw.
|
|
62
|
+
- Marginals mapped onto the SCM's values by rank matching after the SCM (Iman and Conover,
|
|
63
|
+
1982), instead of scamd's root marginals: each column gets exactly its drawn marginal and the
|
|
64
|
+
SCM supplies only the dependence.
|
|
65
|
+
- Categoricals by thresholds at drawn level shares with permuted labels (TabICL v1).
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "tabdgp"
|
|
3
|
+
version = "0.0.1"
|
|
4
|
+
description = "A data-generating process for grouped and flat tables, matched to a registry of real tables"
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
license = "MIT"
|
|
7
|
+
license-files = ["LICENSE"]
|
|
8
|
+
authors = [{ name = "Alex Kipnis", email = "adkipnis@users.noreply.github.com" }]
|
|
9
|
+
requires-python = ">=3.14"
|
|
10
|
+
classifiers = [
|
|
11
|
+
"Development Status :: 1 - Planning",
|
|
12
|
+
"Intended Audience :: Science/Research",
|
|
13
|
+
"Topic :: Scientific/Engineering",
|
|
14
|
+
"Programming Language :: Python :: 3.14",
|
|
15
|
+
"Operating System :: OS Independent",
|
|
16
|
+
]
|
|
17
|
+
dependencies = []
|
|
18
|
+
|
|
19
|
+
[project.urls]
|
|
20
|
+
Repository = "https://github.com/adkipnis/tabdgp"
|
|
21
|
+
Issues = "https://github.com/adkipnis/tabdgp/issues"
|
|
22
|
+
Roadmap = "https://github.com/adkipnis/tabdgp/blob/main/ROADMAP.md"
|
|
23
|
+
|
|
24
|
+
[dependency-groups]
|
|
25
|
+
dev = [
|
|
26
|
+
"pytest",
|
|
27
|
+
"hypothesis",
|
|
28
|
+
"ruff",
|
|
29
|
+
]
|
|
30
|
+
|
|
31
|
+
[build-system]
|
|
32
|
+
requires = ["hatchling>=1.27"] # PEP 639 licence expression and licence files
|
|
33
|
+
build-backend = "hatchling.build"
|
|
34
|
+
|
|
35
|
+
[tool.hatch.build.targets.wheel]
|
|
36
|
+
packages = ["src/tabdgp"]
|
|
37
|
+
|
|
38
|
+
[tool.ruff]
|
|
39
|
+
line-length = 100
|
|
40
|
+
|
|
41
|
+
[tool.ruff.format]
|
|
42
|
+
quote-style = "single"
|
|
43
|
+
|
|
44
|
+
[tool.pytest.ini_options]
|
|
45
|
+
testpaths = ["tests"]
|
|
46
|
+
addopts = "-m 'not slow' --import-mode=importlib"
|
|
47
|
+
markers = [
|
|
48
|
+
"slow: draws thousands of datasets (the proofs against mixedbench's registry); runs by `-m slow`",
|
|
49
|
+
]
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"""The README is rendered on PyPI, where relative links break, so every link points to main."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import re
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
|
|
8
|
+
README = Path(__file__).parents[1] / 'README.md'
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def test_readme_links_are_absolute() -> None:
|
|
12
|
+
targets = re.findall(r'\]\(([^)]+)\)', README.read_text())
|
|
13
|
+
relative = [target for target in targets if not target.startswith('https://')]
|
|
14
|
+
assert relative == []
|
tabdgp-0.0.1/uv.lock
ADDED
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
version = 1
|
|
2
|
+
revision = 3
|
|
3
|
+
requires-python = ">=3.14"
|
|
4
|
+
|
|
5
|
+
[[package]]
|
|
6
|
+
name = "colorama"
|
|
7
|
+
version = "0.4.6"
|
|
8
|
+
source = { registry = "https://pypi.org/simple" }
|
|
9
|
+
sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" }
|
|
10
|
+
wheels = [
|
|
11
|
+
{ url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" },
|
|
12
|
+
]
|
|
13
|
+
|
|
14
|
+
[[package]]
|
|
15
|
+
name = "hypothesis"
|
|
16
|
+
version = "6.169.0"
|
|
17
|
+
source = { registry = "https://pypi.org/simple" }
|
|
18
|
+
dependencies = [
|
|
19
|
+
{ name = "sortedcontainers" },
|
|
20
|
+
]
|
|
21
|
+
sdist = { url = "https://files.pythonhosted.org/packages/b7/b7/fcddfc235d1ab24b831e99ad3385361e87eb4fed427f527a7f15866214ad/hypothesis-6.169.0.tar.gz", hash = "sha256:b65749d7f7a2fddfb106bb57c9902db4ab25ce8724c821f4af50cc58891a6b7b", size = 510164, upload-time = "2026-10-11T06:30:11.324Z" }
|
|
22
|
+
wheels = [
|
|
23
|
+
{ url = "https://files.pythonhosted.org/packages/46/77/f9618aea42a2130798678346c9ea7a8bba5698d87987e7df80e4287d663b/hypothesis-6.169.0-cp311-abi3-macosx_10_12_x86_64.whl", hash = "sha256:e9e896e0175f0ccc4d3cabfdc704b363f0ccc84c7a3fee83ff7915015d9f8292", size = 790354, upload-time = "2026-10-11T06:29:11.368Z" },
|
|
24
|
+
{ url = "https://files.pythonhosted.org/packages/c2/a3/1bc6f290a39e0d5d2111207cd6ad7a3fea3ea5b1e4ed7eecba2285e5dca1/hypothesis-6.169.0-cp311-abi3-macosx_11_0_arm64.whl", hash = "sha256:7196caf24090cbacbff198d6a05c621b41cba6730240b06d0d70aebecec018a3", size = 785843, upload-time = "2026-10-11T06:29:22.091Z" },
|
|
25
|
+
{ url = "https://files.pythonhosted.org/packages/4a/15/bce76740ac85d8554ca21667222e9c142058358df7fd189a5747672b255a/hypothesis-6.169.0-cp311-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5137579522957acd2ac0b75f63ab997d1606af133fa99e1f00e40c36352d6560", size = 1113614, upload-time = "2026-10-11T06:28:42.055Z" },
|
|
26
|
+
{ url = "https://files.pythonhosted.org/packages/48/59/461ac4e614079c4762cc545f73cce0ab0b31d8cc10a3d942136b4c939442/hypothesis-6.169.0-cp311-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ff4a20d78f9e9c1c5d2f8c70b0cd64b3e05be187dd78c9ceb53c1b35ca6c68c1", size = 1143771, upload-time = "2026-10-11T06:28:45.496Z" },
|
|
27
|
+
{ url = "https://files.pythonhosted.org/packages/cf/b5/848f2d5b0447a3cf7c3d2de00701bce8a3d323ec6592baa2c64c857987f7/hypothesis-6.169.0-cp311-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:280ae28120be35792d8fe0ecdf8cd37978842b6646721e257100d24939377f21", size = 1138312, upload-time = "2026-10-11T06:29:56.305Z" },
|
|
28
|
+
{ url = "https://files.pythonhosted.org/packages/0a/2b/eeac69999eeaa45354f6bc491ecd2ae163e6ac1bf3761cea21690625e48a/hypothesis-6.169.0-cp311-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:76f04d874d2b3e0af583dbfefb6ba5a87059a4cc4ad07f74d4c1e35a350a6c02", size = 1190587, upload-time = "2026-10-11T06:28:07.344Z" },
|
|
29
|
+
{ url = "https://files.pythonhosted.org/packages/53/63/1db41f8e3e4aa348b90e28e7059a75fa788f375cb2e06218684767a5df8c/hypothesis-6.169.0-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b9a681b0b1a11faccfc26947bf53c4b00eae7b1f49c435d7e1f76a9ea5ab224", size = 1156021, upload-time = "2026-10-11T06:29:18.175Z" },
|
|
30
|
+
{ url = "https://files.pythonhosted.org/packages/0b/86/d60fe736ff11a31c3a908f50b2b1ef04d4746a9cd9ff8c9a89e09e166fcb/hypothesis-6.169.0-cp311-abi3-manylinux_2_31_riscv64.whl", hash = "sha256:657ba124452b321c3e9fcb90d2ae7b1fa98a0584cde0790dd94359d1ad73a342", size = 1112353, upload-time = "2026-10-11T06:30:02.413Z" },
|
|
31
|
+
{ url = "https://files.pythonhosted.org/packages/25/46/00f848d26bc013915dcf4427f229567b6a2760886d90a9aeb8694d5695d9/hypothesis-6.169.0-cp311-abi3-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:74c3af6a0dc9a6e15b8e875455aa790183524cbbb8a1bd64cb06a77c767c8d92", size = 1151311, upload-time = "2026-10-11T06:28:05.72Z" },
|
|
32
|
+
{ url = "https://files.pythonhosted.org/packages/b9/b3/91ef45be347c8ae1a5602708ab29a11670b030ad78c67f516ace925187d4/hypothesis-6.169.0-cp311-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:90f928cdce3aa1252d5d2d02cd347535c9b8c4fad3aea5ea45c74a319197f654", size = 1288743, upload-time = "2026-10-11T06:28:56.972Z" },
|
|
33
|
+
{ url = "https://files.pythonhosted.org/packages/f2/50/c0f12b457474a30034d48b8eed6345b6d36d6f14834082c2f29cf0d814d4/hypothesis-6.169.0-cp311-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:6f2b1a7512a8961d84ce92f33921fd297f12e3da5ebf490c9de383532307f56b", size = 1416963, upload-time = "2026-10-11T06:28:33.393Z" },
|
|
34
|
+
{ url = "https://files.pythonhosted.org/packages/b5/26/6cdc5f10779af18abd847a195f0cbbb79661d9c4dcfe70d10210c5b396c0/hypothesis-6.169.0-cp311-abi3-musllinux_1_2_i686.whl", hash = "sha256:e0e597cbc93c2a8c7e4c7823039d291ba2c3b15f2105c346463a99c0cd41889c", size = 1370880, upload-time = "2026-10-11T06:28:47.213Z" },
|
|
35
|
+
{ url = "https://files.pythonhosted.org/packages/41/0a/7c6aecb765ffa257bfe582efa7446c999c09459b7dcca2a60dade37a8b7f/hypothesis-6.169.0-cp311-abi3-musllinux_1_2_ppc64le.whl", hash = "sha256:149cd4905da8db8f7385b83dd73d8d1fa459ec327f369e9b8dcca5d3a3358549", size = 1267674, upload-time = "2026-10-11T06:29:23.766Z" },
|
|
36
|
+
{ url = "https://files.pythonhosted.org/packages/c0/85/a958ca273d9436bb7fed05e62c5fb978238d5789165046f13154f1294b70/hypothesis-6.169.0-cp311-abi3-musllinux_1_2_riscv64.whl", hash = "sha256:00b317f00bc41be393cb681b6684e6d912bff1da673be1e719d6ca7b314b78dd", size = 1282637, upload-time = "2026-10-11T06:29:50.717Z" },
|
|
37
|
+
{ url = "https://files.pythonhosted.org/packages/3c/7a/a4d14c21b31e94ecc886ff5fbd68d534598796f848bfaaf3a9e7e13a1d90/hypothesis-6.169.0-cp311-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:96582616bb7de9533f8c5efdba4c5ea1b87457052148f04e53ff6da2e10f8fb8", size = 1322553, upload-time = "2026-10-11T06:29:05.887Z" },
|
|
38
|
+
{ url = "https://files.pythonhosted.org/packages/a6/ec/77363e885adfea72e4a6e2f613cf7aea4e1107689666665c18e621cf609c/hypothesis-6.169.0-cp311-abi3-win32.whl", hash = "sha256:aa9cc053858d3a43f59569ca1203dbb2819b1738674fe426b8139229102e4286", size = 676707, upload-time = "2026-10-11T06:29:58.08Z" },
|
|
39
|
+
{ url = "https://files.pythonhosted.org/packages/59/4f/0c586fabb76b30a643f5a9b3dbf4463909cac405bb44bfd8c72046d787c3/hypothesis-6.169.0-cp311-abi3-win_amd64.whl", hash = "sha256:43aeb55dbcae56e2dc91caa6bc3e6b1a2863f5ee0e1ba2a8c9a70ff453d6a42c", size = 683369, upload-time = "2026-10-11T06:28:21.568Z" },
|
|
40
|
+
{ url = "https://files.pythonhosted.org/packages/e0/1a/ec298d9ee10d7c267e3d8bf886b2d27571628a65dee6238baf36e2275742/hypothesis-6.169.0-cp311-abi3-win_arm64.whl", hash = "sha256:4e00d21ce5e125e78c6ff43388c60f66969e2753e99dacaf2845c81f16b6adc1", size = 681146, upload-time = "2026-10-11T06:29:03.809Z" },
|
|
41
|
+
{ url = "https://files.pythonhosted.org/packages/5a/c3/266159710ddf8d2ca594686cfe349597417f7e6d5cc8d299c5f179fb8ee6/hypothesis-6.169.0-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:ba0494c5be4c5aef90aae7bc6e5c7ee431f27f4594ab4829d4dd47c20d4ad2f9", size = 792160, upload-time = "2026-10-11T06:28:30.306Z" },
|
|
42
|
+
{ url = "https://files.pythonhosted.org/packages/6c/a3/6ffbd303f1f6c2d5d6366024ce104bee175fd7d570ce795029f8f8506c54/hypothesis-6.169.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:6f8c559b34c143bdb88ef4871e68747017050569313e42b68835b6e4e98f0acb", size = 783754, upload-time = "2026-10-11T06:28:00.236Z" },
|
|
43
|
+
{ url = "https://files.pythonhosted.org/packages/f2/cf/7b61a2e12652cb11ec8f3b81b8ff5c227e4f211b845943d4e4a2d5e73f0a/hypothesis-6.169.0-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:078eeecc48d8361a39f63bab150f4098371e537bfd64c0cd1444912a7e269592", size = 1113176, upload-time = "2026-10-11T06:30:09.094Z" },
|
|
44
|
+
{ url = "https://files.pythonhosted.org/packages/96/24/dced7321227420c63de73e57a48e1d2fd2732e32b0d2abb643c8630e1e09/hypothesis-6.169.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b9ac3957d9b5da1d846f66ad17a793835b7e4b59892dc6f74005c709f16ad208", size = 1155753, upload-time = "2026-10-11T06:28:23.477Z" },
|
|
45
|
+
{ url = "https://files.pythonhosted.org/packages/26/68/97ede862a9cf65e42338c0643b62d96bd02643b85d029b918aa357aeffe3/hypothesis-6.169.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:eb49c6433578ebc815d2a86315dcb2598c0d138ab4f674d59d9896d6fbc7102a", size = 1287760, upload-time = "2026-10-11T06:28:27.106Z" },
|
|
46
|
+
{ url = "https://files.pythonhosted.org/packages/2b/97/03435e5d9f81e831e4b9b9bc88712b945ea4b8e48b52e76aa9c8a8d9cf8e/hypothesis-6.169.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:aa998bfdc1b13706e944219be55025fe4cdf63a8e30d97b15e6d0ce2ad14d57d", size = 1322223, upload-time = "2026-10-11T06:27:54.341Z" },
|
|
47
|
+
{ url = "https://files.pythonhosted.org/packages/de/0c/79dc8be75c1eca2cfaa0ccbf36caef1f7ef18c73654b4d9b4e3cb276e568/hypothesis-6.169.0-cp314-cp314-pyemscripten_2026_0_wasm32.whl", hash = "sha256:d4edcb680604e5895577214395d01864f6c68adc2c007f5ad364653cc954fe93", size = 623152, upload-time = "2026-10-11T06:29:13.041Z" },
|
|
48
|
+
{ url = "https://files.pythonhosted.org/packages/f0/4e/4c8e34699b0f79457245e15d7d9d6c0fb13881913a04740532b7fd5df5bc/hypothesis-6.169.0-cp314-cp314-win_amd64.whl", hash = "sha256:d0836e03ef8a3162d000d837deafbb1f0fc573078f46c7c0a8bdee0c4f289e41", size = 680803, upload-time = "2026-10-11T06:29:25.788Z" },
|
|
49
|
+
{ url = "https://files.pythonhosted.org/packages/88/e2/4cb686970f3ffb0b0dc61a16c6a27f5029008373517671c443396c95bc85/hypothesis-6.169.0-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:575017acc9f12f5dc80a3f67089d40745ba95c218d60751bc0eaa25e0c42203c", size = 790544, upload-time = "2026-10-11T06:28:58.611Z" },
|
|
50
|
+
{ url = "https://files.pythonhosted.org/packages/f9/41/a319aecd1dfe3d2f2cad3ea8e3ec7162cba6954d2f32eff79e91b51a5ae4/hypothesis-6.169.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:47c180e7176ed529232d8c74292c80c41837f5e5bd3e8dee687bf24a861ceb25", size = 782197, upload-time = "2026-10-11T06:29:09.431Z" },
|
|
51
|
+
{ url = "https://files.pythonhosted.org/packages/86/6e/e7d2cacbdb4d29436bb822cba6ffdc35bf4976877f8c6b17a1c8e719f506/hypothesis-6.169.0-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c7dd2bf18e569d0a36cccf7f25239e39e5fec0e81d48a1e65f9e8d0cce85ef9b", size = 1111061, upload-time = "2026-10-11T06:28:50.178Z" },
|
|
52
|
+
{ url = "https://files.pythonhosted.org/packages/21/2b/f2bd549a927c70605c0a80e7003fb3e73a29d020de862cd4326b23de24a0/hypothesis-6.169.0-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:031dc57f707f2d7aa64d652f582ee3cbb5d760c56db0268e10a93e4ba6a802f0", size = 1154548, upload-time = "2026-10-11T06:28:25.148Z" },
|
|
53
|
+
{ url = "https://files.pythonhosted.org/packages/46/68/b7bbcd755b819988ed5dffb8e3c71c4e663f6db551409a1daefb12ceb6b2/hypothesis-6.169.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:eb45a192fcccd0220d980feeafdc89b9d7ce49b0343a31f34075dcac71432c2a", size = 1285944, upload-time = "2026-10-11T06:29:14.727Z" },
|
|
54
|
+
{ url = "https://files.pythonhosted.org/packages/28/2e/b4cdf89eae136e7bb5052ee2b6a76c4a125f0a6317c7954f88a046090354/hypothesis-6.169.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:f8be62e2c59055995353e929eeb01003796fbcde75a260d7f77ece88ee57be06", size = 1321091, upload-time = "2026-10-11T06:29:35.341Z" },
|
|
55
|
+
{ url = "https://files.pythonhosted.org/packages/43/0d/9aee786b177aded81a5ea2f5a7ec5c0b3766b69b5cbb6ef23fb620d89a94/hypothesis-6.169.0-cp314-cp314t-win_amd64.whl", hash = "sha256:2fe0dfcd8cd9dd846d9c35c2a0d9fe697fae42ed25368c6aa7db4a6b4c2ea4a9", size = 680518, upload-time = "2026-10-11T06:28:40.535Z" },
|
|
56
|
+
{ url = "https://files.pythonhosted.org/packages/48/32/85618cc42fc9088d0abeb90d62fa16fa52324855d59853a84437ecad0c78/hypothesis-6.169.0-cp315-abi3.abi3t-macosx_10_12_x86_64.whl", hash = "sha256:6bb65a6d0b327e3446baa535a86b645f68d09cf8e838d9b386ae26a2f4e7d829", size = 789864, upload-time = "2026-10-11T06:28:04.247Z" },
|
|
57
|
+
{ url = "https://files.pythonhosted.org/packages/11/ac/2441c1a1db15d1e94659d02505d374c9e40932090c036b03d4c92bf5e41c/hypothesis-6.169.0-cp315-abi3.abi3t-macosx_11_0_arm64.whl", hash = "sha256:01f9c4660bf2627ef36558f3e0f20c746ba30d666e18a2f5af0abc7c71bad695", size = 781885, upload-time = "2026-10-11T06:29:31.743Z" },
|
|
58
|
+
{ url = "https://files.pythonhosted.org/packages/b7/38/0ff5b49df3bf71cb7470bc47b3b9bb67c0ff90056f8de43df3208ac548df/hypothesis-6.169.0-cp315-abi3.abi3t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d754678d75d815c89a3ec0b174fb48df00671fc4ec157983a252f96a9b4872e8", size = 1110308, upload-time = "2026-10-11T06:29:45.02Z" },
|
|
59
|
+
{ url = "https://files.pythonhosted.org/packages/06/36/64a2ea6272694b00352e5d9cd53901037477f7850d0be9fba4878ab14cd7/hypothesis-6.169.0-cp315-abi3.abi3t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6c25e3458f6feedae16962790f58100b3f62c0c81f61c26bf091c55048e0c7b7", size = 1141630, upload-time = "2026-10-11T06:29:40.92Z" },
|
|
60
|
+
{ url = "https://files.pythonhosted.org/packages/00/dc/a292b35d6563d9fff37410898cd39685d4f5dde16d96ace4e2b486e33a4f/hypothesis-6.169.0-cp315-abi3.abi3t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3cfb0cb4964698c60b3756c74a4def1dd20e296cc622ec2313ccbce06e1a6f49", size = 1134877, upload-time = "2026-10-11T06:28:37.177Z" },
|
|
61
|
+
{ url = "https://files.pythonhosted.org/packages/47/6c/cd0770da746c852251a98618abc46edabd2864f7ca9642f193dd694ccbae/hypothesis-6.169.0-cp315-abi3.abi3t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e0ea13627863ee38040ce4bd2841a98f29d27bb404fb1460f0d750750da18a6d", size = 1188583, upload-time = "2026-10-11T06:29:59.951Z" },
|
|
62
|
+
{ url = "https://files.pythonhosted.org/packages/aa/c7/ff5a591b32d2e7f3f1da09bcd81eee133bd23fce971dadeb51d3d87af718/hypothesis-6.169.0-cp315-abi3.abi3t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fa1d423b3d84357331e9cffb3d62c01cfbb08206e102005b858d096695d73210", size = 1153697, upload-time = "2026-10-11T06:28:35.397Z" },
|
|
63
|
+
{ url = "https://files.pythonhosted.org/packages/7c/9c/178b6b9371c7d5beefef7cbf5e8746e48ed044852908feccd57db21d3b56/hypothesis-6.169.0-cp315-abi3.abi3t-manylinux_2_31_riscv64.whl", hash = "sha256:307f9aaf1eb3d323488cacd2b4f7c0b05ec637be1216b31aa47d0288a4ad163a", size = 1108825, upload-time = "2026-10-11T06:28:38.918Z" },
|
|
64
|
+
{ url = "https://files.pythonhosted.org/packages/6f/26/19c06b74cae9949ff18f2bd9a6579310c37499ef46772ecb49d28a72fcd5/hypothesis-6.169.0-cp315-abi3.abi3t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:78b7b0ab7ccbfd8e6250573418859474ef0f8ef7906fcb3b639b6ceccb75af81", size = 1147441, upload-time = "2026-10-11T06:28:15.491Z" },
|
|
65
|
+
{ url = "https://files.pythonhosted.org/packages/da/fa/d3638853d5bb2862545c34ba9b101211a5a1066e7a1c25679f828135d3b8/hypothesis-6.169.0-cp315-abi3.abi3t-musllinux_1_2_aarch64.whl", hash = "sha256:9e6d460c82340b18ad5b49e120df495f78b954c884d3c4f1ea0ca7b2d3bfe4ff", size = 1284816, upload-time = "2026-10-11T06:29:07.632Z" },
|
|
66
|
+
{ url = "https://files.pythonhosted.org/packages/56/76/d6ecdd89b3ccbb7af89a0f2504e0bdb840848cc7fd9bffd0fbeee14b4218/hypothesis-6.169.0-cp315-abi3.abi3t-musllinux_1_2_armv7l.whl", hash = "sha256:1a321d2e407b21e63d5e10e657a5d5d0def640e3c4388918485bce328f066ccb", size = 1414409, upload-time = "2026-10-11T06:28:17.298Z" },
|
|
67
|
+
{ url = "https://files.pythonhosted.org/packages/7f/94/12165c54ba410e3efe21cb4fdb24ca46f609e6b1fb5d170c5a1c07ab62ab/hypothesis-6.169.0-cp315-abi3.abi3t-musllinux_1_2_i686.whl", hash = "sha256:8e196d16686c9ee439aed446ae5dbfc67ff10f6596d27590f64ccb2952801dbb", size = 1367536, upload-time = "2026-10-11T06:29:37.166Z" },
|
|
68
|
+
{ url = "https://files.pythonhosted.org/packages/e0/72/fae9de86e2dd876c8fd42caa3c33cc514b9426f5ed04d3d6044db818a797/hypothesis-6.169.0-cp315-abi3.abi3t-musllinux_1_2_ppc64le.whl", hash = "sha256:6ea93e30342ddb8a8f3e404718a0b51be5ec5b205aecdf9d900ca938c969a6e2", size = 1263366, upload-time = "2026-10-11T06:28:01.44Z" },
|
|
69
|
+
{ url = "https://files.pythonhosted.org/packages/e4/c8/e82296f440ba5057fd89ab78f013463ac804bc546a80bc15ed870802f6d2/hypothesis-6.169.0-cp315-abi3.abi3t-musllinux_1_2_riscv64.whl", hash = "sha256:c1eab3b6b6aec4cec5c6f57f89d5d827d23ff8463ebd9296c63132579b0a79d3", size = 1280661, upload-time = "2026-10-11T06:28:43.914Z" },
|
|
70
|
+
{ url = "https://files.pythonhosted.org/packages/3b/da/8bcd647d20fc4fa3d79a098d3f9a0672e31253605838278f37341873b896/hypothesis-6.169.0-cp315-abi3.abi3t-musllinux_1_2_x86_64.whl", hash = "sha256:4099543afdbb6c727ba823482b93329b8afff0d2b17d8888151592284c7c3971", size = 1320405, upload-time = "2026-10-11T06:30:06.898Z" },
|
|
71
|
+
{ url = "https://files.pythonhosted.org/packages/a4/55/2e26e757aeea856ba7120fd8eca0cda40531e0847ac28c6937dc25b58f22/hypothesis-6.169.0-cp315-abi3.abi3t-win32.whl", hash = "sha256:764cdb2f9d5351bb40e459ff94f30ff271af8927a6e55a1b72db904794f002b8", size = 673870, upload-time = "2026-10-11T06:27:58.753Z" },
|
|
72
|
+
{ url = "https://files.pythonhosted.org/packages/67/e6/5a780510ce2524aa778e30b729c5fc439d30e2a276856ccf50a19ae73bda/hypothesis-6.169.0-cp315-abi3.abi3t-win_amd64.whl", hash = "sha256:bb4643dd25af96749386d52b0cf7cf97d0a1abc5c4382e0835da9311f9c35112", size = 680232, upload-time = "2026-10-11T06:28:08.786Z" },
|
|
73
|
+
{ url = "https://files.pythonhosted.org/packages/84/10/0869258af64a59319b42776cf22b1881b3183370ff1cbc2111466d595760/hypothesis-6.169.0-cp315-abi3.abi3t-win_arm64.whl", hash = "sha256:b65468d07f1f4483bd8c02581e2c03fd1dc9a1d21e3e9f053c4518cecf1e553b", size = 677992, upload-time = "2026-10-11T06:29:29.982Z" },
|
|
74
|
+
]
|
|
75
|
+
|
|
76
|
+
[[package]]
|
|
77
|
+
name = "iniconfig"
|
|
78
|
+
version = "2.3.1"
|
|
79
|
+
source = { registry = "https://pypi.org/simple" }
|
|
80
|
+
sdist = { url = "https://files.pythonhosted.org/packages/01/e1/2069291243c926a2ff1cd706c7f3eeb9b62144bf60f77c9fb9ff2fb26bd3/iniconfig-2.3.1.tar.gz", hash = "sha256:67f4b9c50da0dedf52af349e7749a80a9057a5031199791b906c3bb3ae878960", size = 21209, upload-time = "2026-10-06T22:48:38.076Z" }
|
|
81
|
+
wheels = [
|
|
82
|
+
{ url = "https://files.pythonhosted.org/packages/56/43/4ca9e49d27a1fcf6bece6f6aec0ea46bb9112489b93d4b688fb415457bdb/iniconfig-2.3.1-py3-none-any.whl", hash = "sha256:9121e2c1fdb355232495be3194c8dfe87ccc2d5dee45947b78e68f499790d7a7", size = 7552, upload-time = "2026-10-06T22:48:36.959Z" },
|
|
83
|
+
]
|
|
84
|
+
|
|
85
|
+
[[package]]
|
|
86
|
+
name = "packaging"
|
|
87
|
+
version = "26.3"
|
|
88
|
+
source = { registry = "https://pypi.org/simple" }
|
|
89
|
+
sdist = { url = "https://files.pythonhosted.org/packages/7d/fa/3944b40b07da9ce895c0e6303a5ab7d53da063554f534556b134a54d6093/packaging-26.3.tar.gz", hash = "sha256:94edc256424af38762eb31306eed28beb9f0efc50a8837492c9d6fd6004aed79", size = 313412, upload-time = "2026-08-04T18:15:28.737Z" }
|
|
90
|
+
wheels = [
|
|
91
|
+
{ url = "https://files.pythonhosted.org/packages/63/34/ba1c580383c9eada3711951fef0795c80b829a078d72188184bcab9dd527/packaging-26.3-py3-none-any.whl", hash = "sha256:d7193f7c8e4e93f444fde0262bf90af30e16fa0ad0ad44cb553c87339b23cd1c", size = 129956, upload-time = "2026-08-04T18:15:27.159Z" },
|
|
92
|
+
]
|
|
93
|
+
|
|
94
|
+
[[package]]
|
|
95
|
+
name = "pluggy"
|
|
96
|
+
version = "1.6.0"
|
|
97
|
+
source = { registry = "https://pypi.org/simple" }
|
|
98
|
+
sdist = { url = "https://files.pythonhosted.org/packages/f9/e2/3e91f31a7d2b083fe6ef3fa267035b518369d9511ffab804f839851d2779/pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3", size = 69412, upload-time = "2025-05-15T12:30:07.975Z" }
|
|
99
|
+
wheels = [
|
|
100
|
+
{ url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size = 20538, upload-time = "2025-05-15T12:30:06.134Z" },
|
|
101
|
+
]
|
|
102
|
+
|
|
103
|
+
[[package]]
|
|
104
|
+
name = "pygments"
|
|
105
|
+
version = "2.21.0"
|
|
106
|
+
source = { registry = "https://pypi.org/simple" }
|
|
107
|
+
sdist = { url = "https://files.pythonhosted.org/packages/49/2e/ced460408999b33da6b31b0021b0f37d329e202d4169aeb164493778f25b/pygments-2.21.0.tar.gz", hash = "sha256:610ca751c9bc2492b38eb9a38a7fbc93edbbb2d7182edaf34e66ae493dee5c8c", size = 5005329, upload-time = "2026-08-17T08:02:48.824Z" }
|
|
108
|
+
wheels = [
|
|
109
|
+
{ url = "https://files.pythonhosted.org/packages/71/46/17f022dd3e953bf20a04a028a21ec746d942f8d2af30fa0f124fa0e6a684/pygments-2.21.0-py3-none-any.whl", hash = "sha256:2363c69b61c4a97c838da3b130dcd6468f4848992b21a82f2a63ec34377137d9", size = 1250147, upload-time = "2026-08-17T08:02:44.912Z" },
|
|
110
|
+
]
|
|
111
|
+
|
|
112
|
+
[[package]]
|
|
113
|
+
name = "pytest"
|
|
114
|
+
version = "9.1.1"
|
|
115
|
+
source = { registry = "https://pypi.org/simple" }
|
|
116
|
+
dependencies = [
|
|
117
|
+
{ name = "colorama", marker = "sys_platform == 'win32'" },
|
|
118
|
+
{ name = "iniconfig" },
|
|
119
|
+
{ name = "packaging" },
|
|
120
|
+
{ name = "pluggy" },
|
|
121
|
+
{ name = "pygments" },
|
|
122
|
+
]
|
|
123
|
+
sdist = { url = "https://files.pythonhosted.org/packages/e4/47/b9efed96c114afcfa3c9d3fe98a76a1d14c74a9e266d397cf6eb64be5e01/pytest-9.1.1.tar.gz", hash = "sha256:1088fbde8f2b49d95a549a195707afa7a76a3ce9bcadc26b6d71f0ffda5fe313", size = 1636369, upload-time = "2026-06-19T10:58:32.857Z" }
|
|
124
|
+
wheels = [
|
|
125
|
+
{ url = "https://files.pythonhosted.org/packages/24/25/1de2678b631f5a49215c6c96fff41ba892b0a34df68d6d80292b1b48aa7f/pytest-9.1.1-py3-none-any.whl", hash = "sha256:37a86b45efb9a47a61a36449063e8e18d0cab3161329fc099eb21783169c4f0c", size = 386536, upload-time = "2026-06-19T10:58:31.347Z" },
|
|
126
|
+
]
|
|
127
|
+
|
|
128
|
+
[[package]]
|
|
129
|
+
name = "ruff"
|
|
130
|
+
version = "0.17.0"
|
|
131
|
+
source = { registry = "https://pypi.org/simple" }
|
|
132
|
+
sdist = { url = "https://files.pythonhosted.org/packages/e9/a7/70debb024dfacda67b8e560cc7511f52b34b9348a8cc8c1ec23036dcd51d/ruff-0.17.0.tar.gz", hash = "sha256:5cd03240d8208a557c2a9655a5cb07ebe36aa6bb35065f97d48c1f6adef5a322", size = 5320554, upload-time = "2026-10-09T19:47:29.248Z" }
|
|
133
|
+
wheels = [
|
|
134
|
+
{ url = "https://files.pythonhosted.org/packages/bc/f8/ee5ab9da6089eae2a33e6008b01deb1eda19992c1c8e10661e98cee1640f/ruff-0.17.0-py3-none-linux_armv6l.whl", hash = "sha256:0e271826af9a20d18c6cfae8c51e82959167c24859686ddd3eb9a7f0842ce81e", size = 10148907, upload-time = "2026-10-09T19:46:38.695Z" },
|
|
135
|
+
{ url = "https://files.pythonhosted.org/packages/9f/d9/2f81fb5a9d580afbb11b1c8ff915233a11f2a1b27405d7991f183c5e1976/ruff-0.17.0-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:5f0ca4a40f81403689c04f12966e22f44e329ae362072d8f1587b7bda87f603b", size = 10224208, upload-time = "2026-10-09T19:46:41.711Z" },
|
|
136
|
+
{ url = "https://files.pythonhosted.org/packages/a7/20/643f3c8f75594f937b2bf74801241c56a2e2b8e139d24dff8b66b28cdd7f/ruff-0.17.0-py3-none-macosx_11_0_arm64.whl", hash = "sha256:cbf7149e0927dc3295d5d64679a4765576eef71b00782b2ae969ef82274d6bb9", size = 9273324, upload-time = "2026-10-09T19:46:44.323Z" },
|
|
137
|
+
{ url = "https://files.pythonhosted.org/packages/ec/91/627700b233d367736cb274f1bd0b47d1f2b12f68878192812bd875adadc3/ruff-0.17.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:13ee90156522998c3037059d8f66885c8adeeaf7643bdce2caceee196ecd23e0", size = 9953190, upload-time = "2026-10-09T19:46:47.155Z" },
|
|
138
|
+
{ url = "https://files.pythonhosted.org/packages/cd/92/91f7b5ed39490f89d6cbf56e1f543c383667a725efa8e2c2dee0f01f5591/ruff-0.17.0-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3d8e4a002a94cd9d0dc48b51dc69d807a172b5b9bf2b668e656424dc5b55ead1", size = 9961746, upload-time = "2026-10-09T19:46:50.098Z" },
|
|
139
|
+
{ url = "https://files.pythonhosted.org/packages/87/c5/7310f9fc63ce11ff6394edbd5e85433dfb0e14c9fbf6ccc97f1538491bc7/ruff-0.17.0-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c0b8a60c06a218c337e1161638d34757f83449243e2db161483ddf948e53ad14", size = 10625483, upload-time = "2026-10-09T19:46:53.379Z" },
|
|
140
|
+
{ url = "https://files.pythonhosted.org/packages/a5/8d/97443f0dca4a03a0bc7629fd396fd494a1cb6666121e38c5075acb217d8f/ruff-0.17.0-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a330178bdffc4205dbf3bda11d93e059e388fd6546f8cdd304501a9160363c0d", size = 11350129, upload-time = "2026-10-09T19:46:56.486Z" },
|
|
141
|
+
{ url = "https://files.pythonhosted.org/packages/9c/0a/c525efd9777be4b6b012e6969a3012648468e7e6c4b3e5b46af69f46e8eb/ruff-0.17.0-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7bb08489e234876fa2da67ae3ea938e9a2156da80293e0e4365abd6973d98329", size = 10906223, upload-time = "2026-10-09T19:47:00.263Z" },
|
|
142
|
+
{ url = "https://files.pythonhosted.org/packages/2c/3c/4a01195d93420cad1175bedad13a515dc8a56f95a6e39789b92e582682f5/ruff-0.17.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc73e7c133e82d55b5f15897b2a442d72c0cb4a0c886c46801ce3c247150b60c", size = 10386314, upload-time = "2026-10-09T19:47:03.057Z" },
|
|
143
|
+
{ url = "https://files.pythonhosted.org/packages/c7/72/1a3951665485a921f6375f91e754a1854d5a645d41acc3642668064ff64d/ruff-0.17.0-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:db4f74c533403ab70fe4007873f6ae0c9f94a8b03158cf48d78788e47cdbe399", size = 10565464, upload-time = "2026-10-09T19:47:05.831Z" },
|
|
144
|
+
{ url = "https://files.pythonhosted.org/packages/90/8c/539b4d8c082f57e18db8ae2be85a460d77861c79dcd5798e32b536a6a06f/ruff-0.17.0-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:3d8cc360e666d1914e47b0777c6906d70cf18891a55532bd0a16844195d70859", size = 10079468, upload-time = "2026-10-09T19:47:08.617Z" },
|
|
145
|
+
{ url = "https://files.pythonhosted.org/packages/e0/b8/84286966db79434e8c26b585b0a0f6897cb3ab1c51a4aa4df10c28488b62/ruff-0.17.0-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:d66de796b726c4801e05fa99a2a8d7a780e107be222486c304ab61765561e866", size = 9958556, upload-time = "2026-10-09T19:47:11.324Z" },
|
|
146
|
+
{ url = "https://files.pythonhosted.org/packages/69/50/27b6eed27b83fcdd5bfa0d52b83231e29094754374698da404d094487ae3/ruff-0.17.0-py3-none-musllinux_1_2_i686.whl", hash = "sha256:c3f268baf004aea944f040623327119527ea231af15f7fb7890e82cea0679589", size = 10352173, upload-time = "2026-10-09T19:47:14.188Z" },
|
|
147
|
+
{ url = "https://files.pythonhosted.org/packages/2a/fa/955399fd13044cd827862044117d784a59e3196f6cce7424908ac9a7f914/ruff-0.17.0-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:864b6c1acb6b0bccf94b5a3938a1531fd09aaca5e5659a2e7bf0f3cf2a685540", size = 10791761, upload-time = "2026-10-09T19:47:16.931Z" },
|
|
148
|
+
{ url = "https://files.pythonhosted.org/packages/ae/bf/024e01e1f6aec87768696725e648ed5b438941341eea8f8100beb681961f/ruff-0.17.0-py3-none-win32.whl", hash = "sha256:5e50aa5b84decd9fe5b0bb0e6f71c3b592f1767ed09faa4b7207d933961e35cd", size = 9904112, upload-time = "2026-10-09T19:47:19.75Z" },
|
|
149
|
+
{ url = "https://files.pythonhosted.org/packages/cc/77/1ee73df41dcc8d1cdb686ee4bc46ea29704ea175feb6b95c78420f631ab8/ruff-0.17.0-py3-none-win_amd64.whl", hash = "sha256:8ab76bcda86dfd28e13776cb5de3c7bcdcf1ae3d37ed761113d1a5a415dc134c", size = 10115585, upload-time = "2026-10-09T19:47:22.698Z" },
|
|
150
|
+
{ url = "https://files.pythonhosted.org/packages/fd/71/eb4f0ccc844aece56963e8578df9c95d4c00f580547d52329d4035d3af18/ruff-0.17.0-py3-none-win_arm64.whl", hash = "sha256:c154c73ff43f9854395e24cac507af13078962e53d2b511605058d22af1fdb88", size = 9872035, upload-time = "2026-10-09T19:47:26.306Z" },
|
|
151
|
+
]
|
|
152
|
+
|
|
153
|
+
[[package]]
|
|
154
|
+
name = "sortedcontainers"
|
|
155
|
+
version = "2.4.0"
|
|
156
|
+
source = { registry = "https://pypi.org/simple" }
|
|
157
|
+
sdist = { url = "https://files.pythonhosted.org/packages/e8/c4/ba2f8066cceb6f23394729afe52f3bf7adec04bf9ed2c820b39e19299111/sortedcontainers-2.4.0.tar.gz", hash = "sha256:25caa5a06cc30b6b83d11423433f65d1f9d76c4c6a0c90e3379eaa43b9bfdb88", size = 30594, upload-time = "2021-05-16T22:03:42.897Z" }
|
|
158
|
+
wheels = [
|
|
159
|
+
{ url = "https://files.pythonhosted.org/packages/32/46/9cb0e58b2deb7f82b84065f37f3bffeb12413f947f9388e4cac22c4621ce/sortedcontainers-2.4.0-py2.py3-none-any.whl", hash = "sha256:a163dcaede0f1c021485e957a39245190e74249897e2ae4b2aa38595db237ee0", size = 29575, upload-time = "2021-05-16T22:03:41.177Z" },
|
|
160
|
+
]
|
|
161
|
+
|
|
162
|
+
[[package]]
|
|
163
|
+
name = "tabdgp"
|
|
164
|
+
version = "0.0.1"
|
|
165
|
+
source = { editable = "." }
|
|
166
|
+
|
|
167
|
+
[package.dev-dependencies]
|
|
168
|
+
dev = [
|
|
169
|
+
{ name = "hypothesis" },
|
|
170
|
+
{ name = "pytest" },
|
|
171
|
+
{ name = "ruff" },
|
|
172
|
+
]
|
|
173
|
+
|
|
174
|
+
[package.metadata]
|
|
175
|
+
|
|
176
|
+
[package.metadata.requires-dev]
|
|
177
|
+
dev = [
|
|
178
|
+
{ name = "hypothesis" },
|
|
179
|
+
{ name = "pytest" },
|
|
180
|
+
{ name = "ruff" },
|
|
181
|
+
]
|