Skip to content

test: integration tests, edge cases, and docs - #113

Open
kaitj wants to merge 6 commits into
feat/generalize-ents/phase4from
feat/generalize-ents/phase5
Open

test: integration tests, edge cases, and docs#113
kaitj wants to merge 6 commits into
feat/generalize-ents/phase4from
feat/generalize-ents/phase5

Conversation

@kaitj

@kaitj kaitj commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

This PR:

Final phase of the generalized entities refactor, building on top of phase 4 (#112) to add testing, fix surfaced bugs, a cleanup pass, and documenting new flags.

  • Tests - combined --filter + --schema in one CLI invocation; S3 entity-filter; edge cases (derivative detection without dataset_description.json, and schema-switch re-indexing
  • *Bug fix - clear_schema_cachhes() now also clears bidsschematools.schema.load_schema's own @lru_cache (previously downstream caches re-populated from still-warm upstream cache)
  • Cleanup - removed dead helpers and associated tests; make docstrings consistent in public vs private methods + trim inline comments
  • Index - populate dataset_type instead of leaving unset
  • Docs - document --filter + --schema in README; note deprecation of --subjects / include_subjects

Type of Change

  • Bug fix
  • Enhancement / feature
  • Documentation
  • Other

Related Issue(s)

n/a


Stack created with GitHub Stacks CLIGive Feedback 💬

@github-actions

github-actions Bot commented Aug 20, 2026

Copy link
Copy Markdown

Coverage

Coverage Report
FileStmtsMissCoverMissing
__init__.py100100% 
__main__.py86891%127, 184, 186–187, 191, 223, 227, 231
_entities.py135299%57, 287
_indexing.py304997%63, 239, 248–249, 439–440, 590, 667, 671
_logging.py31487%33, 39, 41–42
_metadata.py49492%40–41, 63, 68
_pathlib.py21386%19, 21, 23
_schema.py122199%302
_version.py110100% 
pybids
   __init__.py40100% 
   _bidsfile.py381366%63–65, 69–71, 75–77, 81–83, 87
   _layout.py1664573%67, 75, 82, 102, 112–113, 116, 131–132, 145–146, 155–156, 158–162, 166, 168–169, 171–172, 199, 204, 218, 293–295, 355–360, 362, 364–369, 371, 425, 449
   _utils.py14564%40–44
TOTAL9919491% 

Tests Skipped Failures Errors Time
202 0 💤 0 ❌ 0 🔥 26.953s ⏱️

@github-actions

github-actions Bot commented Aug 20, 2026

Copy link
Copy Markdown

Benchmark Results

Local index (1 workers) Remote index (4 workers) Bold query Metadata query Subject query
feat/generalize-ents/phase5 243.448 (243.861 ± 2.436) ms 255.150 (255.144 ± 1.531) s 351.512 (353.984 ± 26.021) µs 386.311 (382.193 ± 23.128) µs 49.508 (52.754 ± 9.812) µs
main 240.811 (240.986 ± 0.831) ms 255.165 (255.075 ± 1.391) s 414.193 (409.696 ± 35.936) µs 404.755 (402.832 ± 33.543) µs 49.668 (50.440 ± 5.761) µs
v2.3.1 246.515 (246.875 ± 1.396) ms 252.899 (252.903 ± 1.594) s 404.942 (403.347 ± 17.309) µs 391.861 (400.596 ± 38.524) µs 48.380 (53.373 ± 13.609) µs
feat/generalize-ents/phase5 vs main ratio ⚪ 1.011 ⚪ 1.000 🟢 0.849 ⚪ 0.954 ⚪ 0.997
feat/generalize-ents/phase5 vs v2.3.1 ratio ⚪ 0.988 ⚪ 1.009 🟢 0.868 ⚪ 0.986 ⚪ 1.023

median (mean ± std)

🔴 Slower   ⚪ No change (<5 %)   🟢 Faster

@kaitj
kaitj marked this pull request as ready for review August 20, 2026 18:14
@kaitj
kaitj force-pushed the feat/generalize-ents/phase5 branch from 60680e8 to 0adb2c4 Compare August 27, 2026 20:30
- Add a "Filtering files" section covering `--filter ENTITY=PATTERN`
syntax, glob support, and OR-within-entity / AND-across-entities
semantics, with working examples
- Flag `--subjects` as deprecated with a pointer to `--filter sub=...`
- Document `--schema` fla, which was previously covered only under
the python api
- Remove shell-prompt prefixes from examples, and tag fences as
appropriate with `sh`
clear_schema_caches() did not actually force a re-read of a changed on-disk
schema. bidsschematools.schema.load_schema is itself lru_cached on the schema
path and sits upstream of every bids2table schema cache, so clearing only the
downstream caches (_load_from_path, entity_arrow_schema, ...) just re-populated
them from the still-warm load_schema cache — a stale adapter was returned.

Clear load_schema's cache too (the root of the chain) so a changed schema file
is genuinely re-resolved.

Tests:
- test_schema_switch_mid_session_uses_new_schema: regression guard proving a
  changed schema file is served stale until clear_schema_caches() is called,
  then re-read.
- test_index_derivative_without_description: a derivative dataset under
  derivatives/ without dataset_description.json is still detected, typed as a
  derivative, and indexed.
Two filter-related coverage gaps from the "Generalize entities" effort:

- tests/test_main.py: test_main_index_filter_and_schema — runs `b2t2 index`
  with BOTH `-f` and `--schema` in a single invocation (no test exercised the
  pair before). Uses a modified copy of the default schema so the effect of
  each flag is observable: asserts the filter reduces the row count (only
  sub-A01) and that the custom schema's description reaches the output column
  metadata via the parquet round-trip.

- tests/test_indexing.py: test_index_dataset_s3_filter — cloud-marked; indexes
  s3://openneuro.org/ds000102 with filters={"sub": "01"} and asserts the filter
  applies (5 rows, all sub-01), matching the local ds102 mirror. Skipped
  automatically when cloudpathlib is unavailable.
Remove functions only reachable from tests:
- _entities.py: get_entity_name, get_entity_regex, get_entity_glob_pattern
- _indexing.py: _is_bids_entity_dir (one-line pattern.fullmatch wrapper)
- their tests in test_entities.py and test_indexing.py

Wire dataset_type into the index. It was set only from DatasetType in
dataset_description.json, so derivatives without a declared type indexed
as null. The description is now read once and enriched with a derived
DatasetType (derivative under a nested parent dir, else raw);
_get_dataset_type takes that description instead of re-reading it.
Consolidate two glob matchers that did the same job (match the bare
value or the key-value form against a pattern):
- _indexing.py: drop _match_entity_name, route its call site
  (_find_bids_entity_dirs) through _match_single; the include filter
  no longer round-trips through two name-sets.
- Extract the shared `format -> char_class` lookup, used by both
  _build_datatype_pattern and _compile_entity_dir_pattern, into
  _schema._char_class_for.
Apply the public/private docstring convention across the package and drop
inline comments that merely restate the code. No functional changes.

- Public API: use structured Google docstrings; add `Returns:` where a
  function returns a value (e.g. `cloudpathlib_is_available`,
  `BIDSLayout.to_df`)
- Private helpers: reduce to concise one-liners, stripping boilerplate
  `Args:`/`Returns:` scaffolding while keeping non-obvious notes in prose
- Trim inline comments that restate the code; keep purpose/why/strategy
  comments (e.g. the legacy `database_path` note)
- Fix stale `bids2table_compat` import examples to `bids2table.pybids`
- Convert `listify` from numpydoc to Google style
- Fix `compatability` -> `compatibility` typo
@kaitj
kaitj force-pushed the feat/generalize-ents/phase5 branch from 0adb2c4 to 12cac21 Compare September 2, 2026 17:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant