Skip to content

[Python] Illegal implicit conversions from C++ functors to function pointers accidentally work from Python #20687

@bgrube

Description

@bgrube

Check duplicate issues.

  • 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

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions