Restore intensitydata.py functional test
|Status:||Rejected||Start date:||02 Aug 2016|
After I have fixed Simulation::getIntensityData ownership within #1558, and the returned Histogram2D object started to be governed by Python,
following snippet has stopped to work in intensitydata.py functional test
def get_axis(): simulation = GISASSimulation() simulation.setDetectorParameters(10, -1.0, 1.0, 100, 0.0, 2.0) data = simulation.getIntensityData() axis = data.getXaxis() return axis def test_axis_ownership(self): axis0 = get_axis() self.assertEqual(10, axis0.getSize())
Meaning, that swig doesn't know that time of life of 'data' should be coupled with time of life of 'axis'. So Python deletes 'data' and 'axis' points to nowhere.
In Py++ such situation was handled by following instructions
cl = mb.class_("IHistogram") cl.member_function("getXaxis").call_policies = call_policies.return_internal_reference() cl.member_function("getYaxis").call_policies = call_policies.return_internal_reference() cl = mb.class_("OutputData<double>") fun = cl.member_functions("getAxis").call_policies = call_policies.return_internal_reference()
Although given case is not used in user examples (seems to be), it was used in my private scripts and one have to be ready that similar case sooner or later will be discovered by some advanced user.Within this item:
- learn how to couple time of life of objects
- uncomment text_axes_ownership subtest in intensitydata.py
#1 Updated by jmfisher over 4 years ago
Note that this is the expected behaviour in C++. getXaxis() returns a raw pointer to the axis, which is owned by the intensity data object. When data goes out of scope, the destructor deletes the axis and any remaining pointers become dangling. The Python bindings are simply wrapping this correct behaviour. The desired behaviour could be achieved by promoting raw pointers to shared pointers (which I suspect is how things were done internally within the old boost::python bindings), but it is probably not worth doing.