root icon indicating copy to clipboard operation
root copied to clipboard

Zero-parameter `TF1` created from C++ functor crashes `TCanvas::SaveAs()` in Python

Open bgrube opened this issue 3 weeks ago • 0 comments

Check duplicate issues.

  • [x] Checked for duplicates

Description

Creating a TF1 from a C++ functor with the number of parameters set to zero and drawing this function into a TCanvas, causes a Python TypeError when attempting to save the canvas as a PDF file.

Reproducer

Running the script tf1bug.py

#!/usr/bin/env python3

import ROOT

# function without parameters
def f1(args, pars):
  return 4.0 * args[0]

# functor without parameters
F2_CPP = """
class Functor {
public:

	Functor()
	{ }

	double
	operator () (
		double* args,
		double*
	) {
		return 4.0 * args[0];
	}
};
"""

if __name__ == "__main__":
  ROOT.gROOT.SetBatch(True)
  fcn1 = ROOT.TF1("f1", f1, 0, 1, 0)  # using a Python function works fine
  ROOT.gInterpreter.Declare(F2_CPP)
  functor = ROOT.Functor()
  fcn2 = ROOT.TF1("f2", functor, 0, 1, 1)  # setting the number of parameters to 1 instead of 0 makes the bug go away
  fcn3 = ROOT.TF1("f3", functor, 0, 1, 0)  # <- setting the number of parameters to 0 causes the bug
  for fcn in (fcn1, fcn2, fcn3):
    canv = ROOT.TCanvas()
    fcn.Draw()
    canv.SaveAs(f"{fcn.GetName()}.pdf")

in ROOT 6.38.00 yields

Info in <TCanvas::Print>: pdf file f1.pdf has been created
Info in <TCanvas::Print>: pdf file f2.pdf has been created
Traceback (most recent call last):
  File "./tf1bug.py", line 35, in <module>
    canv.SaveAs(f"{fcn.GetName()}.pdf")
TypeError: could not convert argument to buffer or nullptr

With ROOT 6.32.20, I get

Info in <TCanvas::Print>: pdf file f1.pdf has been created
Info in <TCanvas::Print>: pdf file f2.pdf has been created
Traceback (most recent call last):
  File "/u/home/bgrube/./tf1bug.py", line 35, in <module>
    canv.SaveAs(f"{fcn.GetName()}.pdf")
TypeError: void TPad::SaveAs(const char* filename = "", Option_t* option = "") =>
    TypeError: double Functor::operator()(double* args, double*) =>
    TypeError: could not convert argument 2 (could not convert argument to buffer or nullptr)

ROOT version

The bug appears at least in versions 6.38.00, 6.36.06, and 6.32.20.

Installation method

pre-built binary

Operating system

Linux and MacOS

Additional context

No response

bgrube avatar Dec 10 '25 23:12 bgrube