Skip to content

Reject unsupported ndarray ranks in isvector - #239

Merged
taughz merged 1 commit into
rai-opensource:masterfrom
MokiMeow:fix-isvector-array-rank
Oct 16, 2026
Merged

taughz merged 1 commit into
rai-opensource:masterfrom
MokiMeow:fix-isvector-array-rank

Conversation

@MokiMeow

@MokiMeow MokiMeow commented Oct 9, 2026 •

Copy link
Copy Markdown

isvector() accepts higher-rank arrays and crashes on zero-dimensional arrays. Require two dimensions before checking row/column shapes, matching its documented contract and preventing homogeneous conversions from silently flattening unsupported inputs. Restore positive controls hidden by a duplicate test name.

Thirteen regressions fail before the fix. Full suites pass on Windows Python 3.10/3.12/3.14 and Linux Python 3.13: 351 passed, three skipped, 18 subtests passed. Changed-file pre-commit checks and package builds pass.

@codecov-commenter

Copy link
Copy Markdown

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@petercorke

Copy link
Copy Markdown
Collaborator

Thank you for your interest in SMTB, and for the careful fix. isvector accepting arrays of three or more dimensions, and raising IndexError on a 0-D array, were real bugs, and the extra len(s) == 2 check is the minimal, correct change. I also appreciate you spotting that a duplicated test_isvector name was silently hiding the first test.

Your e2h/h2e regression test prompted a small follow-up: #240 adds direct tests for those two functions, documents their shape contract (columns are points), and makes h2e raise on input with fewer than two rows. It is independent of this PR.

I've approved this. Merging is up to the RAI maintainers, so it may take a little while. Thanks again!

@petercorke

Copy link
Copy Markdown
Collaborator

A quick note on the failing sphinx / sphinx check: this isn't caused by your change, so please don't worry about it. All of the unit-test jobs and codecov pass.

The docs build itself completes. It fails on its final step, which tries to push the built docs to gh-pages. For pull requests from a fork, GitHub gives the workflow a read-only token, so that push is always rejected with a 403. It would happen to any contributor's PR right now.

The fix is already open as #222, which stops the docs job running on pull requests at all. It's waiting on review by the RAI maintainers. Once that merges, the check will go away, and refreshing this PR (for example with "Update branch") will pick up the fix. There's nothing you need to change on your side.

@taughz taughz mentioned this pull request Oct 11, 2026
17 of 19 tasks
@taughz
taughz merged commit b638e40 into rai-opensource:master Oct 16, 2026
12 of 13 checks passed
taughz pushed a commit that referenced this pull request Oct 16, 2026
…tract (#240)

`e2h` and `h2e` had a single assertion each (N-vector input only). The
matrix path and `h2e`'s per-column scaling were only exercised
indirectly through the pose tests, and the shape contract for 2D input
was undocumented.

**Tests** (`tests/base/test_transformsNd.py`)
- vector input as list, tuple, 1D array and column vector
- matrix input for both functions
- `h2e` scaling by each column's own last element
- `h2e(e2h(x))` and `e2h(h2e(x))` round trips
- `ValueError` for bad types
- a characterization test pinning that a `(1,N)` array is a matrix of N
1-vectors, not a row vector. This documents current behavior rather than
endorsing it, so any change to it is deliberate.

**Behavior change (small)**
- `h2e` now raises `ValueError` for input with fewer than two rows (a
`(1,N)` array, a length-1 vector, or a scalar). Previously it returned
an empty `(0,N)` array, which is never useful: a homogeneous point has
at least two elements. Checked callers in MVTB (`Camera.py`,
`ImageReshape.py`); both pass 3-row arrays.
- `e2h` is unchanged.

**Docstrings** (`spatialmath/base/transformsNd.py`)
- Both functions state the contract up front: each *column* is a point,
rows are never points, with explicit shapes and a note on how to convert
a row vector (pass its transpose).
- `:raises:` entries added; `e2h`'s `:seealso:` pointed at itself, now
`h2e`.

Rank-0 and rank-3 rejection is covered by #239 (`isvector`) and is
deliberately not duplicated here; this PR is independent of it.

Full suite: 355 passed, 3 skipped.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
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.

4 participants