Skip to content

Commit

Permalink
Flumpy: Don't allow converting 1D vectors to vec2/3 (cctbx#648)
Browse files Browse the repository at this point in the history
Previously, a size (3,) array would have erroneously converted
to a 0x3 length vec3.

This is now explicitly forbidden; you must pass at least a (0, 3)
multidimensional array.

Fixes cctbx#439.
  • Loading branch information
ndevenish authored Jul 25, 2023
1 parent 930be09 commit 436a1b6
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 1 deletion.
1 change: 1 addition & 0 deletions newsfragments/439.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
``flumpy``: Fix case where incorrect ``flex.vec2``, ``flex.vec3`` could be generated.
7 changes: 7 additions & 0 deletions src/dxtbx/boost_python/flumpy.cc
Original file line number Diff line number Diff line change
Expand Up @@ -520,6 +520,13 @@ py::object vec_from_numpy(py::array np_array) {

static_assert(VecType<int>::fixed_size == 2 || VecType<int>::fixed_size == 3,
"Only vec2/vec3 supported");

// Only accept arrays that have a dimension higher than 1 - we want
// numpy.array([1,2,3]) to fail but numpy.array([[1,2,3]]) to work
if (np_array.ndim() == 1) {
throw std::invalid_argument("Array for conversion to vec must be multidimensional");
}

// Only accept arrays whose last dimension is the size of this object
if (np_array.shape(np_array.ndim() - 1) != VecType<int>::fixed_size) {
throw std::invalid_argument("Input array last dimension is not size "
Expand Down
10 changes: 9 additions & 1 deletion tests/test_flumpy.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ def test_reverse_numeric_2d(flex_numeric):


def test_numeric_4d(flex_numeric):
#  Check that we can think fourth-dimnesionally
# Check that we can think fourth-dimensionally
grid = flex.grid(1, 9, 8, 5)
fo = flex_numeric(grid)
assert fo.nd() == 4
Expand Down Expand Up @@ -402,3 +402,11 @@ def test_int_long_degeneracy():
npo[0] = 42
assert all(fo[x] == npo[x] for x in range(4))
assert fo[0] == 42


def test_single_entry_vec_from_numpy():
with pytest.raises(ValueError):
flumpy.vec_from_numpy(np.array([2.0, 3.0, 4.0]))
ao = flumpy.vec_from_numpy(np.array([[2.0, 3.0, 4.0]]))
assert len(ao) == 1
assert ao[0] == pytest.approx([2.0, 3.0, 4.0])

0 comments on commit 436a1b6

Please sign in to comment.