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.
Files changed (64) hide show
  1. {tablassert-7.5.1 → tablassert-7.5.2}/CHANGELOG.md +8 -0
  2. {tablassert-7.5.1 → tablassert-7.5.2}/PKG-INFO +1 -1
  3. tablassert-7.5.2/docs/changelog.md +13 -0
  4. {tablassert-7.5.1 → tablassert-7.5.2}/pyproject.toml +2 -2
  5. {tablassert-7.5.1 → tablassert-7.5.2}/src/tablassert/lib.py +9 -2
  6. {tablassert-7.5.1 → tablassert-7.5.2}/tests/test_lib.py +7 -0
  7. {tablassert-7.5.1 → tablassert-7.5.2}/uv.lock +5 -5
  8. tablassert-7.5.1/docs/changelog.md +0 -16
  9. {tablassert-7.5.1 → tablassert-7.5.2}/.github/workflows/docker.yml +0 -0
  10. {tablassert-7.5.1 → tablassert-7.5.2}/.github/workflows/docs.yml +0 -0
  11. {tablassert-7.5.1 → tablassert-7.5.2}/.github/workflows/pipy.yml +0 -0
  12. {tablassert-7.5.1 → tablassert-7.5.2}/.gitignore +0 -0
  13. {tablassert-7.5.1 → tablassert-7.5.2}/.pre-commit-config.yaml +0 -0
  14. {tablassert-7.5.1 → tablassert-7.5.2}/AGENTS.md +0 -0
  15. {tablassert-7.5.1 → tablassert-7.5.2}/CITATION.cff +0 -0
  16. {tablassert-7.5.1 → tablassert-7.5.2}/CONTRIBUTING.md +0 -0
  17. {tablassert-7.5.1 → tablassert-7.5.2}/Dockerfile +0 -0
  18. {tablassert-7.5.1 → tablassert-7.5.2}/LICENSE +0 -0
  19. {tablassert-7.5.1 → tablassert-7.5.2}/README.md +0 -0
  20. {tablassert-7.5.1 → tablassert-7.5.2}/docs/api/fullmap.md +0 -0
  21. {tablassert-7.5.1 → tablassert-7.5.2}/docs/api/lib.md +0 -0
  22. {tablassert-7.5.1 → tablassert-7.5.2}/docs/api/qc.md +0 -0
  23. {tablassert-7.5.1 → tablassert-7.5.2}/docs/api/utils.md +0 -0
  24. {tablassert-7.5.1 → tablassert-7.5.2}/docs/cli.md +0 -0
  25. {tablassert-7.5.1 → tablassert-7.5.2}/docs/configuration/advanced-example.md +0 -0
  26. {tablassert-7.5.1 → tablassert-7.5.2}/docs/configuration/graph.md +0 -0
  27. {tablassert-7.5.1 → tablassert-7.5.2}/docs/configuration/table.md +0 -0
  28. {tablassert-7.5.1 → tablassert-7.5.2}/docs/datassert.md +0 -0
  29. {tablassert-7.5.1 → tablassert-7.5.2}/docs/docker.md +0 -0
  30. {tablassert-7.5.1 → tablassert-7.5.2}/docs/examples/tutorial-data.csv +0 -0
  31. {tablassert-7.5.1 → tablassert-7.5.2}/docs/examples/tutorial-graph.yaml +0 -0
  32. {tablassert-7.5.1 → tablassert-7.5.2}/docs/examples/tutorial-table.yaml +0 -0
  33. {tablassert-7.5.1 → tablassert-7.5.2}/docs/examples.md +0 -0
  34. {tablassert-7.5.1 → tablassert-7.5.2}/docs/index.md +0 -0
  35. {tablassert-7.5.1 → tablassert-7.5.2}/docs/installation.md +0 -0
  36. {tablassert-7.5.1 → tablassert-7.5.2}/docs/tutorial.md +0 -0
  37. {tablassert-7.5.1 → tablassert-7.5.2}/llms.txt +0 -0
  38. {tablassert-7.5.1 → tablassert-7.5.2}/mkdocs.yml +0 -0
  39. {tablassert-7.5.1 → tablassert-7.5.2}/src/tablassert/__init__.py +0 -0
  40. {tablassert-7.5.1 → tablassert-7.5.2}/src/tablassert/cli.py +0 -0
  41. {tablassert-7.5.1 → tablassert-7.5.2}/src/tablassert/downloader.py +0 -0
  42. {tablassert-7.5.1 → tablassert-7.5.2}/src/tablassert/enums.py +0 -0
  43. {tablassert-7.5.1 → tablassert-7.5.2}/src/tablassert/fullmap.py +0 -0
  44. {tablassert-7.5.1 → tablassert-7.5.2}/src/tablassert/ingests.py +0 -0
  45. {tablassert-7.5.1 → tablassert-7.5.2}/src/tablassert/log.py +0 -0
  46. {tablassert-7.5.1 → tablassert-7.5.2}/src/tablassert/models.py +0 -0
  47. {tablassert-7.5.1 → tablassert-7.5.2}/src/tablassert/nlp.py +0 -0
  48. {tablassert-7.5.1 → tablassert-7.5.2}/src/tablassert/progress.py +0 -0
  49. {tablassert-7.5.1 → tablassert-7.5.2}/src/tablassert/qc.py +0 -0
  50. {tablassert-7.5.1 → tablassert-7.5.2}/src/tablassert/utils.py +0 -0
  51. {tablassert-7.5.1 → tablassert-7.5.2}/tests/__init__.py +0 -0
  52. {tablassert-7.5.1 → tablassert-7.5.2}/tests/conftest.py +0 -0
  53. {tablassert-7.5.1 → tablassert-7.5.2}/tests/fixtures/invalid_section_missing_source.yaml +0 -0
  54. {tablassert-7.5.1 → tablassert-7.5.2}/tests/fixtures/minimal_section.yaml +0 -0
  55. {tablassert-7.5.1 → tablassert-7.5.2}/tests/fixtures/minimal_section_with_sections.yaml +0 -0
  56. {tablassert-7.5.1 → tablassert-7.5.2}/tests/test_downloader.py +0 -0
  57. {tablassert-7.5.1 → tablassert-7.5.2}/tests/test_enums.py +0 -0
  58. {tablassert-7.5.1 → tablassert-7.5.2}/tests/test_fullmap.py +0 -0
  59. {tablassert-7.5.1 → tablassert-7.5.2}/tests/test_ingests.py +0 -0
  60. {tablassert-7.5.1 → tablassert-7.5.2}/tests/test_models.py +0 -0
  61. {tablassert-7.5.1 → tablassert-7.5.2}/tests/test_nlp.py +0 -0
  62. {tablassert-7.5.1 → tablassert-7.5.2}/tests/test_progress.py +0 -0
  63. {tablassert-7.5.1 → tablassert-7.5.2}/tests/test_qc.py +0 -0
  64. {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.1
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.1"
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.408",
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()).then(pl.lit("UNSURE")).when(cond).then(pl.lit("YES")).otherwise(pl.lit("NO"))
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.409"
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/51/4e/3aa27f74211522dba7e9cbc3e74de779c6d4b654c54e50a4840623be8014/pyright-1.1.409.tar.gz", hash = "sha256:986ee05beca9e077c165758ad123667c679e050059a2546aa02473930394bc93", size = 4430434, upload-time = "2026-04-23T11:02:03.799Z" }
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/16/6b/330d8ebae582b30c2959a1ef4c3bc344ebde48c2ff0c3f113c4710735e11/pyright-1.1.409-py3-none-any.whl", hash = "sha256:aa3ea228cab90c845c7a60d28db7a844c04315356392aa09fafcee98c8c22fb3", size = 6438161, upload-time = "2026-04-23T11:02:01.309Z" },
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.1"
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.408" },
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