Skip to content

Commit

Permalink
[PyROOT] Retain C++ ownership for TF2, TF3
Browse files Browse the repository at this point in the history
Fixes #16942
  • Loading branch information
vepadulano committed Nov 14, 2024
1 parent 4f6e8bb commit bf3b366
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 0 deletions.
2 changes: 2 additions & 0 deletions bindings/pyroot/pythonizations/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,8 @@ set(py_sources
ROOT/_pythonization/_tdirectory.py
ROOT/_pythonization/_tdirectoryfile.py
ROOT/_pythonization/_tf1.py
ROOT/_pythonization/_tf2.py
ROOT/_pythonization/_tf3.py
ROOT/_pythonization/_tfile.py
ROOT/_pythonization/_tformula.py
ROOT/_pythonization/_tgraph.py
Expand Down
25 changes: 25 additions & 0 deletions bindings/pyroot/pythonizations/python/ROOT/_pythonization/_tf2.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Author: Vincenzo Eduardo Padulano CERN 11/2024

################################################################################
# Copyright (C) 1995-2024, Rene Brun and Fons Rademakers. #
# All rights reserved. #
# #
# For the licensing terms see $ROOTSYS/LICENSE. #
# For the list of contributors see $ROOTSYS/README/CREDITS. #
################################################################################
from . import pythonization

def _TF2_constructor(self, *args, **kwargs):
"""
Forward the arguments to the C++ constructor and retain ownership. This
helps avoiding double deletes due to ROOT automatic memory management.
"""
self._cpp_constructor(*args, **kwargs)
import ROOT
ROOT.SetOwnership(self, False)


@pythonization("TF2")
def pythonize_tf2(klass):
klass._cpp_constructor = klass.__init__
klass.__init__ = _TF2_constructor
25 changes: 25 additions & 0 deletions bindings/pyroot/pythonizations/python/ROOT/_pythonization/_tf3.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Author: Vincenzo Eduardo Padulano CERN 11/2024

################################################################################
# Copyright (C) 1995-2024, Rene Brun and Fons Rademakers. #
# All rights reserved. #
# #
# For the licensing terms see $ROOTSYS/LICENSE. #
# For the list of contributors see $ROOTSYS/README/CREDITS. #
################################################################################
from . import pythonization

def _TF3_constructor(self, *args, **kwargs):
"""
Forward the arguments to the C++ constructor and retain ownership. This
helps avoiding double deletes due to ROOT automatic memory management.
"""
self._cpp_constructor(*args, **kwargs)
import ROOT
ROOT.SetOwnership(self, False)


@pythonization("TF3")
def pythonize_tf3(klass):
klass._cpp_constructor = klass.__init__
klass.__init__ = _TF3_constructor
13 changes: 13 additions & 0 deletions bindings/pyroot/pythonizations/test/memory.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,5 +53,18 @@ def test_tstyle_memory_management(self):
groot.SetStyle(style.GetName())
groot.ForceStyle()

def test_tf2_memory_regulation(self):
"""Regression test for https://github.com/root-project/root/issues/16942"""
# The test is just that the memory regulation works correctly and the
# application does not segfault
f2 = ROOT.TF2("f2", "sin(x)*sin(y)/x/y")


def test_tf3_memory_regulation(self):
"""Make sure TF3 is properly managed by the memory regulation logic"""
# The test is just that the memory regulation works correctly and the
# application does not segfault
f3 = ROOT.TF3("f3","[0] * sin(x) + [1] * cos(y) + [2] * z",0,10,0,10,0,10)

if __name__ == '__main__':
unittest.main()

0 comments on commit bf3b366

Please sign in to comment.