Skip to content

Work with both DASCore branches without importing removed classes - #52

Merged
d-chambers merged 1 commit into
mainfrom
compat/dascore-dev
Aug 13, 2026
Merged

Work with both DASCore branches without importing removed classes#52
d-chambers merged 1 commit into
mainfrom
compat/dascore-dev

Conversation

@d-chambers

@d-chambers d-chambers commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

Description

DASCore's development branch collapses MemorySpool/DirectorySpool/FileSpool into a single dc.Spool and deletes the dascore.clients package, so from dascore.clients.dirspool import DirectorySpool fails at import. That takes down widget discovery entirely — every DerZug entry point fails to load:

ERROR orangecanvas.registry.discovery: An exception occurred while loading entry point 'Spool'
  File "src/derzug/widgets/spool.py", line 31, in <module>
    from dascore.clients.dirspool import DirectorySpool
ModuleNotFoundError: No module named 'dascore.clients.dirspool'

Four more couplings were hiding behind that first ImportError. This PR fixes all five by reaching for public APIs instead of version-specific classes and private helpers, with no branching on a DASCore version anywhere in the code.

Coupling Fix
dascore.clients.dirspool / filespool imports — package deleted New derzug/utils/dascore_compat.py answers spool-kind questions from public accessors (indexer, spool_path)
get_contents() renamed pathsource_path; row ordering and identity tokens read it by name contents_path_column() resolves whichever name is present
Spool.select now validates names against a spool's attrs/coords, so the widgets' distance_min dropdown entries raise selectable_contents_keys() offers the coordinate itself (distance) plus real attributes
slope_filter(notch=...) removed — it was a deprecated alias for invert Both checkboxes fold into invert=
dascore.viz.waterfall._get_scale — private, and imports matplotlib eagerly Calls the public dascore.utils.misc.tukey_fence, which is exactly what that call path computed

Also swapped dascore.core.coords.get_coord for the top-level dc.get_coord.

derzug.utils.dascore_compat is deliberately the single place that knows about the two layouts, so it is the one file to delete when support for the older one is dropped.

User-visible changes

  • Select keys. The Spool and Select widgets no longer offer the flattened distance_min/time_max columns or source-file bookkeeping columns; select on the coordinate itself (distance with a (1000, None) range). Auxiliary coordinates such as latitude are now offered, which they never were before. Workflows saved with an older key keep filtering on it.
  • The Filter widget still shows both a Notch and an Invert checkbox. They now do the same thing — as they effectively already did, since notch=True forced invert — but collapsing them is a UI change I kept out of a compatibility PR. Happy to fold it in if wanted.

Verification

The suite was run against three DASCore versions:

DASCore Result
dev @ dddf0f73 (0.1.21.dev146) 2135 passed, 44 skipped
master @ 64f0c8ed 2135 passed, 44 skipped
released 0.1.16 compat surface only — see note

The 0.1.16 environment cannot run the Qt suite (unrelated broken chardet/Orange install), so it was exercised with a direct script over the Qt-free compat surface and the node-layer spool functions.

All 26 widget entry points load against dev, which is what the original traceback was about.

Checklist

I have (if applicable):

  • referenced the GitHub issue this PR closes.
  • documented new behavior with docstrings and/or a doc page.
  • included tests. See guidelines.
  • run prek run --all-files and pytest tests.
  • for hot-path changes, run python scripts/bench_compare.py --baseline main, pasted the table below, and added the benchmark label. See benchmarking.

Note on prek run --all-files: it also reformats tests/test_views/test_orange_qt.py, which it does on a clean main too — the pinned ruff (v0.4.8) is older than whatever last formatted that file. Left untouched here; it wants its own fix.

Benchmarks

python scripts/bench_compare.py --baseline main --repeat 2 (control -5.8%, within tolerance):

benchmark                                                baseline       head    median       min status
-------------------------------------------------------------------------------------------------------
...rks.py::TestGraphBenchmarks::test_validate_uncached    325.0us    336.1us    +3.4%    -2.5%   --  
...chmarks.py::TestExecutionBenchmarks::test_run_chain    312.8us    321.6us    +2.8%    -1.5%   --  
...chmarks.py::TestExecutionBenchmarks::test_map_chain     1.47ms     1.51ms    +2.5%    -3.0%   --  
...ks.py::TestAnnotationMaskBenchmarks::test_span_mask    396.2us    404.6us    +2.1%    +3.1% noisy   (baseline rel stdev 12%)
...ks.py::TestExecutionBenchmarks::test_get_provenance     70.3us     71.1us    +1.2%    -4.0% noisy   (baseline rel stdev 13%)
...rks.py::TestGraphBenchmarks::test_serialize_to_dict    101.7us    102.3us    +0.6%    -0.0%   --  
...mplingBenchmarks::test_percentile_levels_subsampled    929.8us    934.7us    +0.5%    -2.3%   --  
...chmarks.py::TestTaskBenchmarks::test_port_spec_cold    156.8us    156.3us    -0.4%    -0.6%   --  
...::TestExecutionBenchmarks::test_build_runtime_specs    862.5us    854.8us    -0.9%    -4.1%   --  
...marks.py::TestExecutionBenchmarks::test_run_diamond    205.8us    203.9us    -0.9%    -2.5%   --  
...arks.py::TestGraphBenchmarks::test_topological_sort    265.2us    262.2us    -1.1%    -3.5%   --  
...s.py::TestTaskBenchmarks::test_extract_return_names     1.21ms     1.19ms    -1.4%    +1.4%   --  
...s.py::TestTaskBenchmarks::test_callable_source_hash     1.10ms     1.08ms    -1.6%    +0.3% noisy   (baseline rel stdev 16%)
...rks.py::TestSamplingBenchmarks::test_strided_sample    156.2us    153.6us    -1.7%    -2.8%   --  
...arks.py::TestGraphBenchmarks::test_build_chain_pipe    740.4us    725.8us    -2.0%    -2.2%   --  
...py::TestGraphBenchmarks::test_deserialize_from_dict    123.7us    120.3us    -2.7%    -4.2% noisy   (baseline rel stdev 13%)
...nnotationMaskBenchmarks::test_box_mask_object_dtype    11.15ms    10.80ms    -3.1%    -2.7%   --  
...marks.py::TestTaskBenchmarks::test_task_fingerprint     5.96ms     5.75ms    -3.5%    -1.4% noisy   (baseline rel stdev 34%)
...marks.py::TestTaskBenchmarks::test_port_spec_cached    938.2us    905.0us    -3.5%    -3.4%   --  
...stTaskBenchmarks::test_function_task_class_creation    355.8us    339.7us    -4.5%    +0.8%   --  
...s.py::TestImportBenchmarks::test_import_spool_utils     5.77ms     5.45ms    -5.5%    -9.1%   --  
...::TestGraphBenchmarks::test_ensure_validated_cached    743.2us    702.1us    -5.5%    -5.0%   --  
...s.py::TestExecutionBenchmarks::test_stream_pipeline    105.9us     99.6us    -5.9%    -3.0% noisy   (baseline rel stdev 14%)
...TestAnnotationMaskBenchmarks::test_box_mask_numeric     3.02ms     2.82ms    -6.5%    -2.7% noisy   (baseline rel stdev 14%)
...arks.py::TestImportBenchmarks::test_import_workflow    12.32ms     9.92ms   -19.5%   -21.0% noisy   (baseline rel stdev 31%)

control: -5.8% (ok)

threshold 20%: 0 slower, 0 faster, 25 compared

Nothing regresses past the 20% threshold; the largest slowdown is +3.4% on a benchmark this change does not touch. The one double-digit row (test_import_workflow, -19.5%) is an improvement and flagged noisy (baseline rel stdev 31%).

DASCore's development branch collapses MemorySpool, DirectorySpool, and
FileSpool into one Spool and deletes dascore.clients, so importing
DirectorySpool broke every widget entry point at discovery time. Four
other couplings sat behind that first ImportError: get_contents() renamed
`path` to `source_path`; Spool.select now validates names, so the
`distance_min` entries the select dropdowns offered raise; slope_filter
dropped the long-deprecated `notch` alias for `invert`; and the waterfall
default color levels called a private dascore.viz helper.

Every question DerZug asked by isinstance is now asked through a public
accessor in derzug.utils.dascore_compat -- a spool's indexer, its
spool_path, and which of its contents columns name something selectable.
Nothing branches on a DASCore version, and the module is the one place to
delete when support for the older layout is dropped.

Two user-visible consequences: the Spool and Select widgets offer each
coordinate by name (including auxiliary ones like latitude, which were
never offered before) rather than the flattened `<dim>_min` columns, and
a workflow saved with an older key keeps filtering on it.

Verified against dascore dev, master, and the released 0.1.16.
@d-chambers d-chambers added the benchmark Run the CodSpeed benchmark workflow on this PR label Aug 13, 2026
@d-chambers
d-chambers merged commit 61bf8d7 into main Aug 13, 2026
11 checks passed
@d-chambers
d-chambers deleted the compat/dascore-dev branch August 13, 2026 15:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

benchmark Run the CodSpeed benchmark workflow on this PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant