tablassert 7.5.1__tar.gz → 7.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.
- {tablassert-7.5.1 → tablassert-7.5.2}/CHANGELOG.md +8 -0
- {tablassert-7.5.1 → tablassert-7.5.2}/PKG-INFO +1 -1
- tablassert-7.5.2/docs/changelog.md +13 -0
- {tablassert-7.5.1 → tablassert-7.5.2}/pyproject.toml +2 -2
- {tablassert-7.5.1 → tablassert-7.5.2}/src/tablassert/lib.py +9 -2
- {tablassert-7.5.1 → tablassert-7.5.2}/tests/test_lib.py +7 -0
- {tablassert-7.5.1 → tablassert-7.5.2}/uv.lock +5 -5
- tablassert-7.5.1/docs/changelog.md +0 -16
- {tablassert-7.5.1 → tablassert-7.5.2}/.github/workflows/docker.yml +0 -0
- {tablassert-7.5.1 → tablassert-7.5.2}/.github/workflows/docs.yml +0 -0
- {tablassert-7.5.1 → tablassert-7.5.2}/.github/workflows/pipy.yml +0 -0
- {tablassert-7.5.1 → tablassert-7.5.2}/.gitignore +0 -0
- {tablassert-7.5.1 → tablassert-7.5.2}/.pre-commit-config.yaml +0 -0
- {tablassert-7.5.1 → tablassert-7.5.2}/AGENTS.md +0 -0
- {tablassert-7.5.1 → tablassert-7.5.2}/CITATION.cff +0 -0
- {tablassert-7.5.1 → tablassert-7.5.2}/CONTRIBUTING.md +0 -0
- {tablassert-7.5.1 → tablassert-7.5.2}/Dockerfile +0 -0
- {tablassert-7.5.1 → tablassert-7.5.2}/LICENSE +0 -0
- {tablassert-7.5.1 → tablassert-7.5.2}/README.md +0 -0
- {tablassert-7.5.1 → tablassert-7.5.2}/docs/api/fullmap.md +0 -0
- {tablassert-7.5.1 → tablassert-7.5.2}/docs/api/lib.md +0 -0
- {tablassert-7.5.1 → tablassert-7.5.2}/docs/api/qc.md +0 -0
- {tablassert-7.5.1 → tablassert-7.5.2}/docs/api/utils.md +0 -0
- {tablassert-7.5.1 → tablassert-7.5.2}/docs/cli.md +0 -0
- {tablassert-7.5.1 → tablassert-7.5.2}/docs/configuration/advanced-example.md +0 -0
- {tablassert-7.5.1 → tablassert-7.5.2}/docs/configuration/graph.md +0 -0
- {tablassert-7.5.1 → tablassert-7.5.2}/docs/configuration/table.md +0 -0
- {tablassert-7.5.1 → tablassert-7.5.2}/docs/datassert.md +0 -0
- {tablassert-7.5.1 → tablassert-7.5.2}/docs/docker.md +0 -0
- {tablassert-7.5.1 → tablassert-7.5.2}/docs/examples/tutorial-data.csv +0 -0
- {tablassert-7.5.1 → tablassert-7.5.2}/docs/examples/tutorial-graph.yaml +0 -0
- {tablassert-7.5.1 → tablassert-7.5.2}/docs/examples/tutorial-table.yaml +0 -0
- {tablassert-7.5.1 → tablassert-7.5.2}/docs/examples.md +0 -0
- {tablassert-7.5.1 → tablassert-7.5.2}/docs/index.md +0 -0
- {tablassert-7.5.1 → tablassert-7.5.2}/docs/installation.md +0 -0
- {tablassert-7.5.1 → tablassert-7.5.2}/docs/tutorial.md +0 -0
- {tablassert-7.5.1 → tablassert-7.5.2}/llms.txt +0 -0
- {tablassert-7.5.1 → tablassert-7.5.2}/mkdocs.yml +0 -0
- {tablassert-7.5.1 → tablassert-7.5.2}/src/tablassert/__init__.py +0 -0
- {tablassert-7.5.1 → tablassert-7.5.2}/src/tablassert/cli.py +0 -0
- {tablassert-7.5.1 → tablassert-7.5.2}/src/tablassert/downloader.py +0 -0
- {tablassert-7.5.1 → tablassert-7.5.2}/src/tablassert/enums.py +0 -0
- {tablassert-7.5.1 → tablassert-7.5.2}/src/tablassert/fullmap.py +0 -0
- {tablassert-7.5.1 → tablassert-7.5.2}/src/tablassert/ingests.py +0 -0
- {tablassert-7.5.1 → tablassert-7.5.2}/src/tablassert/log.py +0 -0
- {tablassert-7.5.1 → tablassert-7.5.2}/src/tablassert/models.py +0 -0
- {tablassert-7.5.1 → tablassert-7.5.2}/src/tablassert/nlp.py +0 -0
- {tablassert-7.5.1 → tablassert-7.5.2}/src/tablassert/progress.py +0 -0
- {tablassert-7.5.1 → tablassert-7.5.2}/src/tablassert/qc.py +0 -0
- {tablassert-7.5.1 → tablassert-7.5.2}/src/tablassert/utils.py +0 -0
- {tablassert-7.5.1 → tablassert-7.5.2}/tests/__init__.py +0 -0
- {tablassert-7.5.1 → tablassert-7.5.2}/tests/conftest.py +0 -0
- {tablassert-7.5.1 → tablassert-7.5.2}/tests/fixtures/invalid_section_missing_source.yaml +0 -0
- {tablassert-7.5.1 → tablassert-7.5.2}/tests/fixtures/minimal_section.yaml +0 -0
- {tablassert-7.5.1 → tablassert-7.5.2}/tests/fixtures/minimal_section_with_sections.yaml +0 -0
- {tablassert-7.5.1 → tablassert-7.5.2}/tests/test_downloader.py +0 -0
- {tablassert-7.5.1 → tablassert-7.5.2}/tests/test_enums.py +0 -0
- {tablassert-7.5.1 → tablassert-7.5.2}/tests/test_fullmap.py +0 -0
- {tablassert-7.5.1 → tablassert-7.5.2}/tests/test_ingests.py +0 -0
- {tablassert-7.5.1 → tablassert-7.5.2}/tests/test_models.py +0 -0
- {tablassert-7.5.1 → tablassert-7.5.2}/tests/test_nlp.py +0 -0
- {tablassert-7.5.1 → tablassert-7.5.2}/tests/test_progress.py +0 -0
- {tablassert-7.5.1 → tablassert-7.5.2}/tests/test_qc.py +0 -0
- {tablassert-7.5.1 → tablassert-7.5.2}/tests/test_utils.py +0 -0
|
@@ -2,6 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project are documented in this file.
|
|
4
4
|
|
|
5
|
+
## 7.5.2 - 2026-07-01
|
|
6
|
+
|
|
7
|
+
### Changed
|
|
8
|
+
- `sig()` in `lib.py` now emits a third significance label, `"INCONCLUSIVE"`, for p-values that fall between the existing significance `cutoff` (default `0.05`, inclusive) and a new `threshold` parameter (default `0.10`, exclusive). A p-value `p` is now mapped as: null → `"UNSURE"`; `p <= cutoff` → `"YES"`; `cutoff < p < threshold` → `"INCONCLUSIVE"`; `p >= threshold` → `"NO"`. The upper bound is exclusive so `0.10` (and the `0.1` `NO` cases in the existing tests) continue to map to `"NO"`. `threshold` is added to `sig()`'s signature alongside `cutoff`; the function remains wired into `Tcode.collect()` at its default arguments, so builds are unaffected unless a caller overrides the new bound.
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- One regression test in `test_lib.py` (`test_sig_marks_inconclusive_band`) asserting all four bands in a single frame: a value at/below cutoff (`YES`), a value in the inconclusive range (`INCONCLUSIVE`), and a value at the exclusive threshold (`NO`).
|
|
12
|
+
|
|
5
13
|
## 7.5.1 - 2026-07-01
|
|
6
14
|
|
|
7
15
|
### Changed
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: tablassert
|
|
3
|
-
Version: 7.5.
|
|
3
|
+
Version: 7.5.2
|
|
4
4
|
Summary: Extract knowledge assertions from tabular data into NCATS Translator-compliant KGX NDJSON — declaratively, with entity resolution and quality control built in.
|
|
5
5
|
Project-URL: Homepage, https://github.com/SkyeAv/Tablassert
|
|
6
6
|
Project-URL: Source, https://github.com/SkyeAv/Tablassert
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
The canonical release history lives in the repository root at [`CHANGELOG.md`](https://github.com/SkyeAv/Tablassert/blob/main/CHANGELOG.md).
|
|
4
|
+
|
|
5
|
+
## Current Release Notes
|
|
6
|
+
|
|
7
|
+
## 7.5.2 - 2026-07-01
|
|
8
|
+
|
|
9
|
+
### Changed
|
|
10
|
+
- `sig()` in `lib.py` now emits a third significance label, `"INCONCLUSIVE"`, for p-values that fall between the existing significance `cutoff` (default `0.05`, inclusive) and a new `threshold` parameter (default `0.10`, exclusive). A p-value `p` is now mapped as: null → `"UNSURE"`; `p <= cutoff` → `"YES"`; `cutoff < p < threshold` → `"INCONCLUSIVE"`; `p >= threshold` → `"NO"`. The upper bound is exclusive so `0.10` (and the `0.1` `NO` cases in the existing tests) continue to map to `"NO"`. `threshold` is added to `sig()`'s signature alongside `cutoff`; the function remains wired into `Tcode.collect()` at its default arguments, so builds are unaffected unless a caller overrides the new bound.
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
- One regression test in `test_lib.py` (`test_sig_marks_inconclusive_band`) asserting all four bands in a single frame: a value at/below cutoff (`YES`), a value in the inconclusive range (`INCONCLUSIVE`), and a value at the exclusive threshold (`NO`).
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "tablassert"
|
|
3
|
-
version = "7.5.
|
|
3
|
+
version = "7.5.2"
|
|
4
4
|
description = "Extract knowledge assertions from tabular data into NCATS Translator-compliant KGX NDJSON — declaratively, with entity resolution and quality control built in."
|
|
5
5
|
authors = [
|
|
6
6
|
{ name = "Skye Lane Goetz", email = "sgoetz@isbscience.org" }
|
|
@@ -92,7 +92,7 @@ qc-cuda = [
|
|
|
92
92
|
dev = [
|
|
93
93
|
"mkdocs>=1.6.1",
|
|
94
94
|
"pre-commit>=4.5.1",
|
|
95
|
-
"pyright>=1.1.
|
|
95
|
+
"pyright>=1.1.411",
|
|
96
96
|
"pytest>=9.0.2",
|
|
97
97
|
"pytest-cov>=7.1.0",
|
|
98
98
|
"ruff>=0.15.6",
|
|
@@ -5,7 +5,7 @@ import operator
|
|
|
5
5
|
from collections.abc import Iterable
|
|
6
6
|
from contextlib import ExitStack
|
|
7
7
|
from functools import reduce
|
|
8
|
-
from operator import add, eq, le
|
|
8
|
+
from operator import add, eq, le, lt
|
|
9
9
|
from os.path import basename
|
|
10
10
|
from pathlib import Path
|
|
11
11
|
from typing import TYPE_CHECKING, Any, Callable, Literal, Optional, Self, Union
|
|
@@ -132,6 +132,7 @@ def explode(lf: pl.LazyFrame, col: str, delimiter: str) -> pl.LazyFrame:
|
|
|
132
132
|
def sig(
|
|
133
133
|
lf: pl.LazyFrame,
|
|
134
134
|
cutoff: float = 0.05, # pyright: ignore
|
|
135
|
+
threshold: float = 0.10,
|
|
135
136
|
col: str = "p value",
|
|
136
137
|
out: str = "significant",
|
|
137
138
|
) -> pl.LazyFrame:
|
|
@@ -145,7 +146,13 @@ def sig(
|
|
|
145
146
|
expr: pl.Expr = pl.col(chosen).cast(pl.Float64, strict=False)
|
|
146
147
|
cond: pl.Expr = le(expr, cutoff)
|
|
147
148
|
cutoff: pl.Expr = (
|
|
148
|
-
pl.when(expr.is_null())
|
|
149
|
+
pl.when(expr.is_null())
|
|
150
|
+
.then(pl.lit("UNSURE"))
|
|
151
|
+
.when(cond)
|
|
152
|
+
.then(pl.lit("YES"))
|
|
153
|
+
.when(lt(expr, threshold))
|
|
154
|
+
.then(pl.lit("INCONCLUSIVE"))
|
|
155
|
+
.otherwise(pl.lit("NO"))
|
|
149
156
|
)
|
|
150
157
|
return lf.with_columns(cutoff.alias(out))
|
|
151
158
|
else:
|
|
@@ -358,6 +358,13 @@ def test_sig_marks_null_as_unsure() -> None:
|
|
|
358
358
|
assert list(result["significant"]) == ["UNSURE", "YES", "NO"]
|
|
359
359
|
|
|
360
360
|
|
|
361
|
+
# ? sig Marks P-Values Between Cutoff And Threshold As INCONCLUSIVE
|
|
362
|
+
def test_sig_marks_inconclusive_band() -> None:
|
|
363
|
+
lf: pl.LazyFrame = pl.DataFrame({"p value": [0.01, 0.07, 0.1]}).lazy()
|
|
364
|
+
result: pl.DataFrame = lib.sig(lf).collect()
|
|
365
|
+
assert list(result["significant"]) == ["YES", "INCONCLUSIVE", "NO"]
|
|
366
|
+
|
|
367
|
+
|
|
361
368
|
# ? numeric_columns Matches Any Column With P Value In The Name
|
|
362
369
|
def test_numeric_columns_matches_p_value_substring() -> None:
|
|
363
370
|
names: list[str] = ["p value", "adjusted p value", "log p value", "subject"]
|
|
@@ -1737,15 +1737,15 @@ wheels = [
|
|
|
1737
1737
|
|
|
1738
1738
|
[[package]]
|
|
1739
1739
|
name = "pyright"
|
|
1740
|
-
version = "1.1.
|
|
1740
|
+
version = "1.1.411"
|
|
1741
1741
|
source = { registry = "https://pypi.org/simple" }
|
|
1742
1742
|
dependencies = [
|
|
1743
1743
|
{ name = "nodeenv" },
|
|
1744
1744
|
{ name = "typing-extensions" },
|
|
1745
1745
|
]
|
|
1746
|
-
sdist = { url = "https://files.pythonhosted.org/packages/
|
|
1746
|
+
sdist = { url = "https://files.pythonhosted.org/packages/7e/ab/265f7dc69d28113ebba19092e57b075f41543b2ed048429c5f56e2b88eac/pyright-1.1.411.tar.gz", hash = "sha256:d885a0551f2e763b089a02702174e7f4ba77548cddabc972ab86d1f7f1b0f998", size = 4112861, upload-time = "2026-06-25T02:14:06.37Z" }
|
|
1747
1747
|
wheels = [
|
|
1748
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
1748
|
+
{ url = "https://files.pythonhosted.org/packages/0a/49/385be530a6a5b78d1cbcd5c2e38debc8959a2fc6bdb716f4e581002979fc/pyright-1.1.411-py3-none-any.whl", hash = "sha256:dc7c72a8e2700c55baa127554040e067041ea53ccfd50bf96308cc4291c7d5d9", size = 6181526, upload-time = "2026-06-25T02:14:04.691Z" },
|
|
1749
1749
|
]
|
|
1750
1750
|
|
|
1751
1751
|
[[package]]
|
|
@@ -2340,7 +2340,7 @@ wheels = [
|
|
|
2340
2340
|
|
|
2341
2341
|
[[package]]
|
|
2342
2342
|
name = "tablassert"
|
|
2343
|
-
version = "7.5.
|
|
2343
|
+
version = "7.5.2"
|
|
2344
2344
|
source = { editable = "." }
|
|
2345
2345
|
dependencies = [
|
|
2346
2346
|
{ name = "cyclopts" },
|
|
@@ -2422,7 +2422,7 @@ provides-extras = ["rt", "qc", "qc-cuda"]
|
|
|
2422
2422
|
dev = [
|
|
2423
2423
|
{ name = "mkdocs", specifier = ">=1.6.1" },
|
|
2424
2424
|
{ name = "pre-commit", specifier = ">=4.5.1" },
|
|
2425
|
-
{ name = "pyright", specifier = ">=1.1.
|
|
2425
|
+
{ name = "pyright", specifier = ">=1.1.411" },
|
|
2426
2426
|
{ name = "pytest", specifier = ">=9.0.2" },
|
|
2427
2427
|
{ name = "pytest-cov", specifier = ">=7.1.0" },
|
|
2428
2428
|
{ name = "ruff", specifier = ">=0.15.6" },
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
# Changelog
|
|
2
|
-
|
|
3
|
-
The canonical release history lives in the repository root at [`CHANGELOG.md`](https://github.com/SkyeAv/Tablassert/blob/main/CHANGELOG.md).
|
|
4
|
-
|
|
5
|
-
## Current Release Notes
|
|
6
|
-
|
|
7
|
-
## 7.5.1 - 2026-07-01
|
|
8
|
-
|
|
9
|
-
### Changed
|
|
10
|
-
- Numeric annotation columns are now coerced and emitted as controlled-notation strings in NDJSON output instead of raw values. Two new pipeline steps wired into `Tcode.collect()` (`lib.py`): `clean_numeric()` lazily casts matching columns to `Float64` with `strict=False` (non-numeric entries drop to null), and `format_numeric()` renders them as strings — p-value columns (any name containing `"p value"`, case-insensitive) in scientific notation (`{:.4e}`), and `relationship strength` / `sample size` in decimal general format (`{:.4g}`, ≥4 significant figures). Non-matching columns are left untouched, and nulls are subsequently dropped by `strip_nulls()`. `math_op()` now also casts with `strict=False` so it tolerates residual junk in numeric annotation columns. `format_numeric()` formats via numpy-backed batch conversion rather than `map_elements` for throughput.
|
|
11
|
-
- Removed dead `pl.Config(set_fmt_float=...)` and `pl.Config(float_precision=...)` context managers from `compile_graph()` (`lib.py`); they were no-ops for NDJSON serialization (`write_ndjson` emits raw f64 via serde shortest-repr and ignores float display options), and the `fmt`/`precision` parameters of `compile_graph()` were removed alongside them.
|
|
12
|
-
- Fixed an off-by-one in the build/validate progress bar so each section loop now shows the configuration currently being processed instead of the last-completed one. `PipelineProgress.section_loop()` (`progress.py`) previously returned a single `advance(info)` callback that set the description and ticked the completed counter together, called after each item's work — so while section *K* ran the bar still displayed section *K−1*. It now returns a `(start, advance)` pair: `start(info)` updates the description to the in-flight item without incrementing, and `advance()` ticks the counter afterwards (so the counter never claims an in-flight item is complete). All five call sites in `cli.py` (TCode build, Collect, Subgraph, Graph, Validate) were updated to `start(...)` before the work and `advance()` after; the long-running Collect and Subgraph stages continue to show the full `format_section_oneline()` summary (including the `CONFIG` name) of the in-flight section.
|
|
13
|
-
|
|
14
|
-
### Added
|
|
15
|
-
- Fifteen regression tests in `test_lib.py` covering `numeric_columns()` detection (p-value substring, exact-name match, case-insensitivity), `clean_numeric()` (parse/coerce numeric and scientific notation, null out non-numeric junk, leave non-matching columns untouched, noop, idempotent on Float64), `format_numeric()` (scientific notation for p-value, decimal general format for relationship strength/sample size, null preservation, floating-point-noise cleaning, noop), null-stripped NDJSON rows, `compile_graph()` NDJSON emission, and `sig()` operating over a cleaned Float64 p-value column.
|
|
16
|
-
- Three regression tests in `tests/test_progress.py` pinning the new two-callback contract: `start` shows the in-flight item with the counter still at zero, `advance` ticks the counter without altering the description, and a `start`/`advance` cycle keeps the description synced to the current item rather than the previous one.
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|