Skip to content

Conversation

@d-chambers
Copy link
Contributor

@d-chambers d-chambers commented Sep 9, 2025

Description

This PR allows patch.chunk to drop conflicting, non dimensional coordinates when conflict = 'drop'

Checklist

I have (if applicable):

  • referenced the GitHub issue this PR closes.
  • documented the new feature with docstrings or appropriate doc page.
  • included a test. See testing guidelines.
  • your name has been added to the contributors page (docs/contributors.md).
  • added the "ready_for_review" tag once the PR is ready to be reviewed.

Summary by CodeRabbit

  • New Features

    • Option to drop conflicting non-dimensional coordinates during merges.
    • Patch merging now respects conflict settings: "drop" or "keep_first" can discard conflicting private coordinates instead of failing.
    • Merge operations raise clearer errors when conflicts remain, with guidance on conflict-handling options.
  • Documentation

    • Parameter docs updated to describe the new conflict-dropping behavior.
  • Tests

    • Added tests covering merge behavior for conflicting private/non-dimensional coordinates (drop and error paths).

@d-chambers d-chambers added the spool related to Spool class label Sep 9, 2025
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Sep 9, 2025

Walkthrough

Adds an optional drop_conflicting flag to merge_coord_managers to allow skipping conflicting non-dimensional coordinates during merges. Patch merging is updated to derive this behavior from merge_kwargs["conflicts"] (treating "drop" and "keep_first" as dropping). Tests added to verify both drop and error paths.

Changes

Cohort / File(s) Summary of Changes
Coord merge API and logic
dascore/utils/coordmanager.py
Added drop_conflicting: bool = False parameter to merge_coord_managers, corrected docstring wording, and implemented logic to skip conflicting non-dimensional coords when drop_conflicting=True; otherwise raise CoordMergeError (message now suggests using spool.chunk with conflict='drop').
Patch merge integration
dascore/utils/patch.py
Threaded drop_conflicting through _get_new_coord to merge_coord_managers. Determined drop_conf_coords from merge_kwargs["conflicts"] (True for values in {"drop","keep_first"}), and passed it into merge calls to enable conditional dropping during forced merges.
Tests: patch chunking
tests/test_core/test_patch_chunk.py
Added class-scoped fixture creating two patches with conflicting private (non-dimensional) coords and test test_merge_with_conflicting_private_coords asserting that conflict="drop" removes private coords and merges successfully, while default behavior raises CoordMergeError.
Tests: coord manager utilities
tests/test_utils/test_coordmanager_utils.py
Added fixture producing two coord managers with conflicting non-dimensional coords and test_conflicting_non_dimensional_coords verifying merge succeeds with drop_conflicting=True (no keys starting with _) and raises CoordMergeError when drop_conflicting=False. Introduced NumPy usage for coord generation.

Pre-merge checks (2 passed, 1 warning)

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Description Check ⚠️ Warning The PR description includes the correct sections but leaves all checklist items unchecked despite adding tests and updating docstrings, and it does not confirm adding the contributor to the contributors page or the ready_for_review tag required by the template. Please update the checklist to check the boxes for including tests and documenting the feature with docstrings, add your name to docs/contributors.md if applicable, and add the “ready_for_review” tag once this PR is ready for review.
✅ Passed checks (2 passed)
Check name Status Explanation
Title Check ✅ Passed The title succinctly conveys the primary change by stating that chunking can now drop non-dimensional coordinates, matching the core behavior introduced in the changeset and providing clear context to reviewers.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4ecf168 and e3a6ef3.

📒 Files selected for processing (3)
  • dascore/utils/coordmanager.py (3 hunks)
  • tests/test_core/test_patch_chunk.py (2 hunks)
  • tests/test_utils/test_coordmanager_utils.py (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • tests/test_core/test_patch_chunk.py
  • dascore/utils/coordmanager.py
  • tests/test_utils/test_coordmanager_utils.py
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (13)
  • GitHub Check: test_code_min_deps (windows-latest, 3.12)
  • GitHub Check: test_code (windows-latest, 3.12)
  • GitHub Check: test_code (macos-latest, 3.12)
  • GitHub Check: test_code (windows-latest, 3.11)
  • GitHub Check: test_code (windows-latest, 3.13)
  • GitHub Check: test_code (ubuntu-latest, 3.13)
  • GitHub Check: test_code (ubuntu-latest, 3.11)
  • GitHub Check: test_code (ubuntu-latest, 3.10)
  • GitHub Check: test_code (windows-latest, 3.10)
  • GitHub Check: test_code (macos-latest, 3.13)
  • GitHub Check: test_code (macos-latest, 3.11)
  • GitHub Check: test_code (ubuntu-latest, 3.12)
  • GitHub Check: test_code (macos-latest, 3.10)
✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch merge_private_coords

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov
Copy link

codecov bot commented Sep 9, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 99.88%. Comparing base (7139676) to head (e3a6ef3).
⚠️ Report is 2 commits behind head on master.

Additional details and impacted files
@@           Coverage Diff           @@
##           master     #532   +/-   ##
=======================================
  Coverage   99.88%   99.88%           
=======================================
  Files         122      122           
  Lines       10035    10040    +5     
=======================================
+ Hits        10023    10028    +5     
  Misses         12       12           
Flag Coverage Δ
unittests 99.88% <100.00%> (+<0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
dascore/utils/coordmanager.py (1)

114-129: Fix incorrect coord selection in _get_merged_coords (uses dim instead of coord_name).
This produces wrong concatenation when merging non-dim coordinates aligned to the merge dim. It also sets dims from the dim key instead of the coordinate being merged.

-        for coord_name in coords_to_merge:
-            merge_coords = [x.coord_map[dim] for x in managers]
+        for coord_name in coords_to_merge:
+            merge_coords = [x.coord_map[coord_name] for x in managers]
             axis = managers[0].dim_map[coord_name].index(dim)
@@
-            dims = managers[0].dim_map[dim]
+            dims = managers[0].dim_map[coord_name]

Consider adding a unit test that includes an extra non-dimensional coordinate (sharing the merge dim) to catch this path.

🧹 Nitpick comments (6)
dascore/utils/coordmanager.py (3)

21-22: Type hint the new parameter for clarity and API hygiene.
Add a bool annotation to drop_conflicting.

-    drop_conflicting=False,
+    drop_conflicting: bool = False,

24-24: Fix docstring typo.
"Merger" → "Merge".

-    Merger coordinate managers along a specified dimension.
+    Merge coordinate managers along a specified dimension.

80-85: Use the public API name in the error hint.
spool.chunk takes conflict=..., not conflicts=....

-                "Coordinate managers cannot be merged. Try using "
-                "spool.chunk with conflicts='drop'."
+                "Coordinate managers cannot be merged. Try using "
+                "spool.chunk with conflict='drop'."
tests/test_core/test_patch_chunk.py (3)

273-287: Optional: prefer Generator over legacy RandomState.
Switching to numpy.random.default_rng improves reproducibility patterns going forward.

-        rand = np.random.RandomState(42)
-        c1 = rand.random(random_patch.shape[dist_ax])
-        c2 = rand.random(c1.shape)
+        rng = np.random.default_rng(42)
+        c1 = rng.random(random_patch.shape[dist_ax])
+        c2 = rng.random(c1.shape)

485-490: Fix test docstring (behavior without conflict='drop').
Should raise, not drop.

-        Otherwise they should be dropped.
+        Otherwise it should raise.

496-497: Tiny readability nit.
Use generator form of any().

-        assert not any([x.startswith("_") for x in coord_names])
+        assert not any(x.startswith("_") for x in coord_names)
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7139676 and 4ecf168.

📒 Files selected for processing (4)
  • dascore/utils/coordmanager.py (3 hunks)
  • dascore/utils/patch.py (2 hunks)
  • tests/test_core/test_patch_chunk.py (2 hunks)
  • tests/test_utils/test_coordmanager_utils.py (3 hunks)
🧰 Additional context used
🧬 Code graph analysis (4)
dascore/utils/coordmanager.py (1)
dascore/core/patch.py (1)
  • dims (188-190)
dascore/utils/patch.py (1)
dascore/utils/coordmanager.py (1)
  • merge_coord_managers (17-146)
tests/test_core/test_patch_chunk.py (6)
dascore/examples.py (1)
  • random_patch (29-111)
tests/conftest.py (2)
  • random_patch (282-284)
  • spool (569-571)
dascore/core/coords.py (2)
  • get_coord (1475-1663)
  • coord_range (509-529)
dascore/proc/coords.py (2)
  • get_coord (87-139)
  • update_coords (218-243)
dascore/core/spool.py (3)
  • spool (670-699)
  • chunk (111-158)
  • chunk (511-541)
dascore/exceptions.py (1)
  • CoordMergeError (42-43)
tests/test_utils/test_coordmanager_utils.py (5)
tests/conftest.py (1)
  • cm_basic (106-108)
dascore/core/coords.py (5)
  • index (698-717)
  • get_coord (1475-1663)
  • update (738-751)
  • update (925-927)
  • coord_range (509-529)
dascore/core/coordmanager.py (3)
  • get_coord (990-1009)
  • update (230-286)
  • coord_range (1031-1033)
dascore/utils/coordmanager.py (1)
  • merge_coord_managers (17-146)
dascore/exceptions.py (1)
  • CoordMergeError (42-43)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (17)
  • GitHub Check: test_code (windows-latest, 3.13)
  • GitHub Check: test_code (windows-latest, 3.10)
  • GitHub Check: test_code (windows-latest, 3.11)
  • GitHub Check: test_code (macos-latest, 3.11)
  • GitHub Check: test_code (windows-latest, 3.12)
  • GitHub Check: test_code (macos-latest, 3.10)
  • GitHub Check: test_code (macos-latest, 3.13)
  • GitHub Check: test_code (ubuntu-latest, 3.13)
  • GitHub Check: test_code (ubuntu-latest, 3.10)
  • GitHub Check: test_code (ubuntu-latest, 3.11)
  • GitHub Check: test_code (ubuntu-latest, 3.12)
  • GitHub Check: test_code_min_deps (macos-latest, 3.12)
  • GitHub Check: test_code_min_deps (windows-latest, 3.13)
  • GitHub Check: test_code_min_deps (ubuntu-latest, 3.13)
  • GitHub Check: test_code_min_deps (windows-latest, 3.12)
  • GitHub Check: test_code_min_deps (ubuntu-latest, 3.12)
  • GitHub Check: test_code_min_deps (macos-latest, 3.13)
🔇 Additional comments (3)
dascore/utils/patch.py (2)

395-400: LGTM: plumbs drop_conflicting through to merge_coord_managers.
Wiring is correct; snap behavior remains unchanged.


422-425: Align drop_conf_coords to only drop on conflicts='drop'
Current logic also treats keep_first as a drop, which extends behavior beyond the PR’s intent. Update to:

-    drop_conf_coords = True if conf in {"drop", "keep_first"} else False
+    drop_conf_coords = conf == "drop"

If keep_first is meant to drop non-dimensional coord conflicts as well, update the documentation to state this explicitly.

tests/test_utils/test_coordmanager_utils.py (1)

163-167: LGTM: exercises both drop and non-drop paths.
Covers the new flag and the error branch.

@d-chambers d-chambers merged commit 4242dc7 into master Sep 10, 2025
22 checks passed
@d-chambers d-chambers deleted the merge_private_coords branch September 10, 2025 07:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

spool related to Spool class

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants