BUG: Backport release 5.4 Disown Python objects adopted by unique_ptr members - #6712
Open
hjmjohnson wants to merge 1 commit into
Open
Conversation
GradientImageFilter::OverrideBoundaryCondition and OptimizerParameters::SetHelper store their raw-pointer argument in a unique_ptr member, but the Python wrapping left ownership with the proxy. Both sides freed the object and the interpreter aborted at shutdown. Apply SWIGTYPE *DISOWN to both parameters and add Python regression tests.
hjmjohnson
marked this pull request as ready for review
July 26, 2026 19:18
Contributor
|
| Filename | Overview |
|---|---|
| Modules/Core/Common/wrapping/itkOptimizerParameters.wrap | Applies the ownership-transfer typemap to the correctly named helper pointer adopted by SetHelper. |
| Modules/Core/Common/wrapping/test/CMakeLists.txt | Registers the new optimizer ownership regression test under Python wrapping builds. |
| Modules/Core/Common/wrapping/test/itkOptimizerParametersOwnershipTest.py | Verifies that SetHelper relinquishes Python ownership of a newly constructed helper. |
| Modules/Filtering/ImageGradient/wrapping/itkGradientImageFilter.wrap | Applies the ownership-transfer typemap across the wrapped image types used by OverrideBoundaryCondition. |
| Modules/Filtering/ImageGradient/wrapping/test/CMakeLists.txt | Registers the gradient ownership test when its required float and two-dimensional wrapping configuration is enabled. |
| Modules/Filtering/ImageGradient/wrapping/test/itkGradientImageFilterOwnershipTest.py | Verifies ownership transfer and exercises the filter after adopting the boundary condition. |
Sequence Diagram
sequenceDiagram
participant Python as Python proxy
participant SWIG as SWIG wrapper
participant Native as C++ object
Python->>SWIG: Pass owned helper/boundary condition
SWIG->>Python: Clear thisown via DISOWN
SWIG->>Native: Invoke adopting setter(raw pointer)
Native->>Native: unique_ptr.reset(pointer)
Note over Python,Native: Native object becomes the sole owner
Reviews (1): Last reviewed commit: "BUG: Disown Python objects adopted by un..." | Re-trigger Greptile
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Backport of #6707 to
release-5.4. Two wrapped ITK methods adopt their raw-pointer argument into astd::unique_ptrmember, but the Python wrapping left ownership with the proxy object. Both sides free it, and the interpreter aborts at shutdown. Fixed by applyingSWIGTYPE *DISOWNto both parameters; no C++ change.Affects
itk.GradientImageFilter.OverrideBoundaryConditionanditk.OptimizerParameters.SetHelper.Reproducer (release-5.4, before this change)
After this change,
thisownisFalsein both cases and the interpreter exits cleanly.Root cause
Both methods take a raw pointer and immediately adopt it:
GradientImageFilter::OverrideBoundaryConditionm_BoundaryCondition.reset(boundaryCondition)itkGradientImageFilter.hxx:45OptimizerParameters::SetHelperm_Helper.reset(helper)itkOptimizerParameters.h:142OptimizerParameters::SetHelperdocuments the intent explicitly: "OptimizerParameters manages the helper once its been assigned."SWIG's default typemap for a raw pointer parameter is non-owning, so the Python proxy keeps
thisown == True. The C++unique_ptrand the Python proxy then both destroy the object.Test plan — built and run against release-5.4
This was not assumed to apply from
main; it was built and tested on arelease-5.4worktree.ITK_WRAP_PYTHON=ONbuild of release-5.4itkGradientImageFilterOwnershipPythonTestitkOptimizerParametersOwnershipPythonTestrelease-5.4Python suite (ctest -R Python)Because the double-free manifests at interpreter shutdown, a non-zero exit code is itself part of the regression check — these tests fail on unpatched
release-5.4even with the assertions removed.Differences from the main-branch change
The
.wrapand.pycontent is identical to #6707. Only the twowrapping/test/CMakeLists.txthunks differ, becauserelease-5.4predates the gersemi restyle — the newitk_python_add_testcalls follow 5.4's local formatting (NAMEon its own line, closing paren attached to the last argument).release-5.4has no.pre-commit-config.yaml, so the pre-commit hooks were not run against this branch.