Browse Source

python: remove py::implicitly_convertible<py::array> for array views.

This now causes construction of SceneFieldData from a 2D view to do
`import numpy` internally because of some extremely crazy internal
behavior (as shown in the now-deleted comment in the code). Turns out
everything still works even without marking the types implicitly
convertible from py::array (as it should, anyway), so I suspect that was
only needed long time ago for some strange reason, or maybe on some
older and no longer supported pybind11 version.

This reverts commit eb6576c6af.
next
Vladimír Vondruš 2 years ago
parent
commit
806a0e46a0
  1. 5
      src/python/corrade/containers.cpp
  2. 35
      src/python/magnum/magnum.cpp

5
src/python/corrade/containers.cpp

@ -24,7 +24,6 @@
*/
#include <pybind11/pybind11.h>
#include <pybind11/numpy.h> /* so ArrayView is convertible from python array */
#include <Corrade/Containers/Array.h>
#include <Corrade/Containers/BitArray.h>
#include <Corrade/Containers/StridedBitArrayView.h>
@ -118,8 +117,6 @@ template<class T> void arrayView(py::class_<Containers::ArrayView<T>, Containers
/* Implicitly convertible from a buffer */
py::implicitly_convertible<py::buffer, Containers::ArrayView<T>>();
/* This is needed for implicit conversion from np.array */
py::implicitly_convertible<py::array, Containers::ArrayView<T>>();
c
/* Constructor */
@ -603,8 +600,6 @@ Containers::Pair<py::object(*)(const char*), void(*)(char*, py::handle)> accesso
template<unsigned dimensions, class T> void stridedArrayView(py::class_<Containers::PyStridedArrayView<dimensions, T>, Containers::PyArrayViewHolder<Containers::PyStridedArrayView<dimensions, T>>>& c) {
/* Implicitly convertible from a buffer */
py::implicitly_convertible<py::buffer, Containers::PyStridedArrayView<dimensions, T>>();
/* This is needed for implicit conversion from np.array */
py::implicitly_convertible<py::array, Containers::PyStridedArrayView<dimensions, T>>();
c
/* Constructor */

35
src/python/magnum/magnum.cpp

@ -90,40 +90,19 @@ template<class T> void imageView(py::class_<T, PyImageViewHolder<T>>& c) {
py::implicitly_convertible<Image<T::Dimensions>, T>();
c
/* Constructors. The variants *not* taking an array view have to be
first, otherwise things fail on systems that don't have numpy
installed:
===================================================================
ERROR: test_init_empty (test.test.ImageView)
-------------------------------------------------------------------
Traceback (most recent call last):
File ".../magnum/test/test.py", line 102, in test_init_empty
b = ImageView2D(storage, PixelFormat.R32F, (8, 8))
ModuleNotFoundError: No module named 'numpy'
This is because of the order in which pybind processes arguments ---
it would first try to match the (PixelFormat, Vector2i, ArrayView)
variant and *somehow* getting all the way to the third argument,
where, because ArrayView is marked as implicitly convertible from
py::array for numpy compatibility, it ends up doing this in numpy.h:
module m = module::import("numpy.core.multiarray");
auto c = m.attr("_ARRAY_API");
Wonderful, isn't it. */
.def(py::init([](const PixelStorage& storage, PixelFormat format, const typename PyDimensionTraits<T::Dimensions, Int>::VectorType& size) {
return T{storage, format, size};
}), "Construct an empty view")
.def(py::init([](PixelFormat format, const typename PyDimensionTraits<T::Dimensions, Int>::VectorType& size) {
return T{format, size};
}), "Construct an empty view")
/* Constructors */
.def(py::init([](const PixelStorage& storage, PixelFormat format, const typename PyDimensionTraits<T::Dimensions, Int>::VectorType& size, const Containers::ArrayView<typename T::Type>& data) {
return pyImageViewHolder(T{storage, format, size, data}, pyObjectHolderFor<Containers::PyArrayViewHolder>(data).owner);
}), "Constructor")
.def(py::init([](PixelFormat format, const typename PyDimensionTraits<T::Dimensions, Int>::VectorType& size, const Containers::ArrayView<typename T::Type>& data) {
return pyImageViewHolder(T{format, size, data}, pyObjectHolderFor<Containers::PyArrayViewHolder>(data).owner);
}), "Constructor")
.def(py::init([](const PixelStorage& storage, PixelFormat format, const typename PyDimensionTraits<T::Dimensions, Int>::VectorType& size) {
return T{storage, format, size};
}), "Construct an empty view")
.def(py::init([](PixelFormat format, const typename PyDimensionTraits<T::Dimensions, Int>::VectorType& size) {
return T{format, size};
}), "Construct an empty view")
.def(py::init([](Image<T::Dimensions>& image) {
return pyImageViewHolder(T{image}, image.data() ? py::cast(image) : py::none{});
}), "Construct a view on an image")

Loading…
Cancel
Save