Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions Modules/Core/Common/wrapping/itkOptimizerParameters.wrap
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ itk_end_wrap_class()

itk_wrap_class("itk::OptimizerParameters")
foreach(t ${types})
# SetHelper stores the argument in a unique_ptr member.
string(APPEND ITK_WRAP_PYTHON_SWIG_EXT
"%apply SWIGTYPE *DISOWN { itkOptimizerParametersHelper${ITKM_${t}} * helper };\n")

itk_wrap_template("${ITKM_${t}}" "${ITKT_${t}}")
endforeach()
itk_end_wrap_class()
5 changes: 5 additions & 0 deletions Modules/Core/Common/wrapping/test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -62,4 +62,9 @@ if(ITK_WRAP_PYTHON)
itkImageLifetimePythonTest
COMMAND
${CMAKE_CURRENT_SOURCE_DIR}/itkImageLifetimeTest.py)
itk_python_add_test(
NAME
itkOptimizerParametersOwnershipPythonTest
COMMAND
${CMAKE_CURRENT_SOURCE_DIR}/itkOptimizerParametersOwnershipTest.py)
endif()
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# ==========================================================================
#
# Copyright NumFOCUS
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0.txt
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# ==========================================================================
"""OptimizerParameters.SetHelper takes ownership of its argument.

Without a DISOWN typemap, Python and the m_Helper unique_ptr both free the helper,
and the interpreter aborts at shutdown. A non-zero exit code from this script is
itself part of the regression check.
"""

import itk

parameters = itk.OptimizerParameters[itk.D](3)
helper = itk.OptimizerParametersHelper[itk.D]()

assert helper.thisown, "Python should own a freshly constructed helper"

parameters.SetHelper(helper)

assert not helper.thisown, "SetHelper must transfer ownership away from Python"

print("Test finished.")
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ foreach(d ${ITK_WRAP_IMAGE_DIMS})
set(vector_dim ${d}) # Wrap only vector dimensions which are the same as image dimensions
foreach(t ${WRAP_ITK_SCALAR})

# OverrideBoundaryCondition stores the argument in a unique_ptr member.
string(APPEND ITK_WRAP_PYTHON_SWIG_EXT
"%apply SWIGTYPE *DISOWN { itkImageBoundaryCondition${ITKM_I${t}${vector_dim}} * boundaryCondition };\n")

if(ITK_WRAP_covariant_vector_float)
itk_wrap_template("${ITKM_I${t}${vector_dim}}${ITKM_F}${ITKM_F}" "${ITKT_I${t}${vector_dim}},${ITKT_F},${ITKT_F}")
endif()
Expand Down
6 changes: 6 additions & 0 deletions Modules/Filtering/ImageGradient/wrapping/test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,10 @@ if(ITK_WRAP_PYTHON
DATA{${test_input_dir}/BrainProtonDensitySlice.png}
${ITK_TEST_OUTPUT_DIR}/GradientMagnitudeRecursiveGaussianImageFilterTest.png
5)

itk_python_add_test(
NAME
itkGradientImageFilterOwnershipPythonTest
COMMAND
${CMAKE_CURRENT_SOURCE_DIR}/itkGradientImageFilterOwnershipTest.py)
endif()
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# ==========================================================================
#
# Copyright NumFOCUS
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0.txt
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# ==========================================================================
"""GradientImageFilter.OverrideBoundaryCondition takes ownership of its argument.

Without a DISOWN typemap, Python and the filter's unique_ptr member both free the
boundary condition, and the interpreter aborts at shutdown. A non-zero exit code
from this script is itself part of the regression check.
"""

import itk

itk.auto_progress(2)

ImageType = itk.Image[itk.F, 2]

filt = itk.GradientImageFilter[ImageType, itk.F, itk.F].New()
boundaryCondition = itk.PeriodicBoundaryCondition[ImageType]()

assert (
boundaryCondition.thisown
), "Python should own a freshly constructed boundary condition"

filt.OverrideBoundaryCondition(boundaryCondition)

assert (
not boundaryCondition.thisown
), "OverrideBoundaryCondition must transfer ownership away from Python"

# The filter must remain usable with the adopted boundary condition.
image = ImageType.New()
region = itk.ImageRegion[2]()
region.SetSize([8, 8])
image.SetRegions(region)
image.Allocate()
image.FillBuffer(1.0)

filt.SetInput(image)
filt.Update()

assert filt.GetOutput().GetLargestPossibleRegion().GetSize()[0] == 8

print("Test finished.")
Loading