Skip to content

Commit c5b0fb1

Browse files
bakpaulhugtalbotfredroy
authored
Use built in method numpy.set_printoptions in addObject/addChild methods to enable numpy 2 (#518)
* Use set_printoptions(legacy=True) in node binfing to force usage of legacy repr for numpy objects. This is ocmpatible with numpy 1 * Patch addChild * Add RAII mechanism to make sure numpy is put back its initial state * Add [[maybe_unused]] Co-authored-by: Frederick Roy <fredroy@users.noreply.github.com> --------- Co-authored-by: Hugo <hugo.talbot@sofa-framework.org> Co-authored-by: Frederick Roy <fredroy@users.noreply.github.com>
1 parent 1219430 commit c5b0fb1

1 file changed

Lines changed: 44 additions & 0 deletions

File tree

bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_Node.cpp

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,9 +235,47 @@ void setFieldsFromPythonValues(Base* self, const py::kwargs& dict)
235235
}
236236
}
237237

238+
class NumpyReprFixerRAII
239+
{
240+
public:
241+
NumpyReprFixerRAII()
242+
{
243+
using namespace pybind11::literals;
244+
245+
m_numpy = py::module_::import("numpy");
246+
const std::string version = py::cast<std::string>(m_numpy.attr("__version__"));
247+
m_majorVersion = std::stoi(version.substr(0,1));
248+
if ( m_majorVersion > 1)
249+
{
250+
m_setPO = m_numpy.attr("set_printoptions");
251+
m_initialState = m_numpy.attr("get_printoptions")();
252+
m_setPO("legacy"_a = true);
253+
}
254+
}
255+
256+
~NumpyReprFixerRAII()
257+
{
258+
if ( m_majorVersion > 1)
259+
{
260+
m_setPO(**m_initialState);
261+
}
262+
}
263+
264+
private:
265+
py::module_ m_numpy;
266+
int m_majorVersion;
267+
py::object m_setPO;
268+
py::dict m_initialState;
269+
270+
};
271+
272+
238273
/// Implement the addObject function.
239274
py::object addObjectKwargs(Node* self, const std::string& type, const py::kwargs& kwargs)
240275
{
276+
//Instantiating this object will make sure the numpy representation is fixed during the call of this function, and comes back to its previous state after
277+
[[maybe_unused]] const NumpyReprFixerRAII numpyReprFixer;
278+
241279
std::string name {};
242280
if (kwargs.contains("name"))
243281
{
@@ -292,6 +330,8 @@ py::object addObjectKwargs(Node* self, const std::string& type, const py::kwargs
292330
if(d)
293331
d->setPersistent(true);
294332
}
333+
334+
295335
return PythonFactory::toPython(object.get());
296336
}
297337

@@ -361,6 +401,9 @@ py::object createObject(Node* self, const std::string& type, const py::kwargs& k
361401

362402
py::object addChildKwargs(Node* self, const std::string& name, const py::kwargs& kwargs)
363403
{
404+
//Instantiating this object will make sure the numpy representation is fixed during the call of this function, and comes back to its previous state after
405+
[[maybe_unused]] const NumpyReprFixerRAII numpyReprFixer;
406+
364407
if (sofapython3::isProtectedKeyword(name))
365408
throw py::value_error("addChild: Cannot call addChild with name " + name + ": Protected keyword");
366409
BaseObjectDescription desc (name.c_str());
@@ -379,6 +422,7 @@ py::object addChildKwargs(Node* self, const std::string& name, const py::kwargs&
379422
d->setPersistent(true);
380423
}
381424

425+
382426
return py::cast(node);
383427
}
384428

0 commit comments

Comments
 (0)